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_CONNECT: a call is answered on either side.
28 * - PORT_STATE_IN_SETUP: the seizing is received, we wait for the first digit.
29 * - PORT_STATE_IN_OVERLAP: the digits are received.
30 * - PORT_STATE_IN_PROCEEDING: the number is complete, a SETUP is indicated.
31 * - PORT_STATE_IN_DISCONNECT: a clear-back was received, an DISCONNECT is indicated.
32 * - PORT_STATE_RELEASE: the clear forward procedure is started.
38 /* ss5 signal states */
40 SS5_STATE_IDLE, /* no signal */
41 SS5_STATE_SEIZING, /* seizing */
42 SS5_STATE_PROCEED_TO_SEND, /* proceed-to-send */
43 SS5_STATE_BUSY_FLASH, /* busy-flash / clear back */
44 SS5_STATE_ACK_BUSY_FLASH, /* acknowledge of busy/answer/clear-back */
45 SS5_STATE_ANSWER, /* answer */
46 SS5_STATE_ACK_ANSWER, /* acknowledge of busy/answer/clear-back */
47 SS5_STATE_FORWARD_TRANSFER, /* forward transfer */
48 SS5_STATE_CLEAR_BACK, /* clear-back */
49 SS5_STATE_ACK_CLEAR_BACK, /* acknowledge of busy/answer/clear-back */
50 SS5_STATE_CLEAR_FORWARD, /* clear-forward */
51 SS5_STATE_RELEASE_GUARD, /* release-guard */
52 SS5_STATE_DIAL_OUT, /* dialing state (transmitter) */
53 SS5_STATE_DIAL_IN, /* dialing state (receiver) */
54 SS5_STATE_DIAL_IN_PULSE, /* dialing state (receiver with pulses) */
55 SS5_STATE_DELAY, /* after signal wait until next signal can be sent */
56 SS5_STATE_DOUBLE_SEIZE, /* in case of a double seize, we make the remote size recognize it */
58 const char *ss5_state_name[] = {
61 "STATE_PROCEED_TO_SEND",
63 "STATE_ACK_BUSY_FLASH",
66 "STATE_FORWARD_TRANSFER",
68 "STATE_ACK_CLEAR_BACK",
69 "STATE_CLEAR_FORWARD",
70 "STATE_RELEASE_GUARD",
73 "STATE_DIAL_IN_PULSE",
80 /* sending signal states */
81 SS5_SIGNAL_SEND_ON, /* sending signal, waiting for acknowledge */
82 SS5_SIGNAL_SEND_ON_RECOG, /* sending signal, receiving ack, waiting for recogition timer */
83 SS5_SIGNAL_SEND_OFF, /* silence, receiving ack, waiting for stop */
84 /* receiving signal states */
85 SS5_SIGNAL_RECEIVE_RECOG, /* receiving signal, waiting for recognition timer */
86 SS5_SIGNAL_RECEIVE, /* receiving signal / send ack, waiting for stop */
87 SS5_SIGNAL_DELAY, /* delay after release guard to prevent ping-pong */
88 /* sending / receiving digit states */
89 SS5_SIGNAL_DIGIT_PAUSE, /* pausing before sending (next) digit */
90 SS5_SIGNAL_DIGIT_ON, /* sending digit */
91 SS5_SIGNAL_PULSE_OFF, /* make */
92 SS5_SIGNAL_PULSE_ON, /* break */
94 const char *ss5_signal_name[] = {
97 "SIGNAL_SEND_ON_RECOG",
99 "SIGNAL_RECEIVE_RECOG",
102 "SIGNAL_DIGIT_PAUSE",
108 /* ss5 signal timers (in samples) */
109 #define SS5_TIMER_AFTER_SIGNAL (100*8) /* wait after signal is terminated */
110 #define SS5_TIMER_KP (100*8) /* duration of KP1 or KP2 digit */
111 #define SS5_TIMER_DIGIT (55*8) /* duration of all other digits */
112 #define SS5_TIMER_PAUSE (55*8) /* pause between digits */
113 #define SS5_TIMER_FORWARD (850*8) /* forward transfer length */
114 #define SS5_TIMER_RECOG_SEIZE (40*8) /* recognition time of seizing / proceed-to-send signal */
115 #define SS5_TIMER_RECOG_OTHER (125*8) /* recognition time of all other f1/f2 signals */
116 #define SS5_TIMER_SIGNAL_LOSS (15*8) /* minimum time of signal loss for a continous signal */
117 #define SS5_TIMER_DOUBLE_SEIZE (850*8) /* double seize length */
118 #define SS5_TIMER_RELEASE_GUARD (850*8) /* be sure to release after clear-forward */
119 #define SS5_TIMER_RELEASE_MAX (2000*8)/* maximum time for release guard to prevent 'double-releasing' */
120 #define SS5_TIMER_RELEASE_DELAY (4000*8)/* wait after release guard to prevent ping-pong */
121 #define BELL_TIMER_BREAK (50*8) /* loop open, tone */
122 #define BELL_TIMER_MAKE (50*8) /* loop closed, no tone */
123 #define BELL_TIMER_PAUSE (800*8) /* interdigit delay */
124 #define BELL_TIMER_RECOG_HANGUP (200*8) /* time to recognize hangup */
125 #define BELL_TIMER_RECOG_END (300*8) /* recognize end of digit */
128 #define SS5_TIMER_OVERLAP 5.0 /* timeout for overlap digits received on outgoing exchange */
134 enum { /* even values are indications, odd values are requests */
137 SS5_PROCEED_TO_SEND_IND,
138 SS5_PROCEED_TO_SEND_REQ,
145 SS5_CLEAR_FORWARD_IND,
146 SS5_CLEAR_FORWARD_REQ,
147 SS5_RELEASE_GUARD_IND,
148 SS5_RELEASE_GUARD_REQ,
151 SS5_DOUBLE_SEIZURE_IND,
152 SS5_DOUBLE_SEIZURE_REQ,
155 SS5_FORWARD_TRANSFER_IND,
156 SS5_FORWARD_TRANSFER_REQ,
158 static struct isdn_message {
162 {"SEIZING RECEIVED", SS5_SEIZING_IND},
163 {"SEIZING SENDING", SS5_SEIZING_REQ},
164 {"PROCEED-TO-SEND RECEIVED", SS5_PROCEED_TO_SEND_IND},
165 {"PROCEED-TO-SEND SENDING", SS5_PROCEED_TO_SEND_REQ},
166 {"BUSY-FLASH RECEIVED", SS5_BUSY_FLASH_IND},
167 {"BUSY-FLASH SENDING", SS5_BUSY_FLASH_REQ},
168 {"ANSWER RECEIVED", SS5_ANSWER_IND},
169 {"ANSWER SENDING", SS5_ANSWER_REQ},
170 {"CLEAR-BACK RECEIVED", SS5_CLEAR_BACK_IND},
171 {"CLEAR-BACK SENDING", SS5_CLEAR_BACK_REQ},
172 {"CLEAR-FORWARD RECEIVED", SS5_CLEAR_FORWARD_IND},
173 {"CLEAR-FORWARD SENDING", SS5_CLEAR_FORWARD_REQ},
174 {"RELEASE-GUARD RECEIVED", SS5_RELEASE_GUARD_IND},
175 {"RELEASE-GUARD SENDING", SS5_RELEASE_GUARD_REQ},
176 {"ACKNOWLEDGE RECEIVED", SS5_ACKNOWLEDGE_IND},
177 {"ACKNOWLEDGE SENDING", SS5_ACKNOWLEDGE_REQ},
178 {"DOUBLE-SEIZURE RECEIVED", SS5_DOUBLE_SEIZURE_IND},
179 {"DOUBLE-SEIZURE SENDING", SS5_DOUBLE_SEIZURE_REQ},
180 {"DIALING RECEIVED", SS5_DIALING_IND},
181 {"DIALING SENDING", SS5_DIALING_REQ},
182 {"FORWARD-TRANSFER RECEIVED", SS5_FORWARD_TRANSFER_IND},
183 {"FORWARD-TRANSFER SENDING", SS5_FORWARD_TRANSFER_REQ},
186 static void ss5_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int channel)
191 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
192 /* select message and primitive text */
194 while(ss5_message[i].name) {
195 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
196 if (ss5_message[i].value == msg) {
197 SCPY(msgtext, ss5_message[i].name);
203 /* init trace with given values */
204 start_trace(mISDNport?mISDNport->portnum:-1,
205 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
206 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
207 port?port->p_dialinginfo.id:NULL,
208 (msg&1)?DIRECTION_OUT:DIRECTION_IN,
210 port?port->p_serial:0,
212 add_trace("channel", NULL, "%d", channel);
213 switch (port->p_type) {
214 case PORT_TYPE_SS5_OUT:
215 add_trace("state", NULL, "outgoing");
217 case PORT_TYPE_SS5_IN:
218 add_trace("state", NULL, "incomming");
221 add_trace("state", NULL, "idle");
228 * changes release tone int busy signal
229 * this makes the line more authentic
231 void Pss5::set_tone(const char *dir, const char *name)
233 if (name && !strcmp(name, "cause_10"))
236 PmISDN::set_tone(dir, name);
240 * creation of static channels
242 void ss5_create_channel(struct mISDNport *mISDNport, int i)
246 struct port_settings port_settings;
248 SPRINT(portname, "%s-%d", mISDNport->name, i+1);
250 memset(&port_settings, 0, sizeof(port_settings));
251 SCPY(port_settings.tones_dir, options.tones_dir);
253 ss5port = new Pss5(PORT_TYPE_SS5_IDLE, mISDNport, portname, &port_settings, i + (i>=15) + 1, 1, B_MODE_TRANSPARENT);
255 FATAL("No memory for Pss5 class.\n");
256 if (!ss5port->p_m_b_channel)
257 FATAL("No bchannel on given index.\n");
259 /* connect channel */
260 bchannel_event(mISDNport, ss5port->p_m_b_index, B_EVENT_USE);
266 * hunt for a free line
267 * this function returns a port object in idle state.
269 class Pss5 *ss5_hunt_line(struct mISDNport *mISDNport)
273 class Pss5 *ss5port = NULL;
274 struct select_channel *selchannel;
276 PDEBUG(DEBUG_SS5, "Entered name=%s\n", mISDNport->name);
277 selchannel = mISDNport->ifport->out_channel;
279 switch(selchannel->channel) {
280 case CHANNEL_FREE: /* free channel */
281 case CHANNEL_ANY: /* any channel */
282 for (i = 0; i < mISDNport->b_num; i++) {
283 port = mISDNport->b_port[i];
284 PDEBUG(DEBUG_SS5, "Checking port %p on index\n", port, i);
287 if (port->p_type == PORT_TYPE_SS5_IN || port->p_type == PORT_TYPE_SS5_OUT)
288 PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because port not idle type.\n",
290 if (port->p_type != PORT_TYPE_SS5_IDLE)
292 ss5port = (class Pss5 *)port;
293 /* is really idle ? */
294 if (ss5port->p_state == PORT_STATE_IDLE
295 && ss5port->p_m_s_state == SS5_STATE_IDLE)
297 PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because p_state=%d, ss5_state=%d.\n",
298 mISDNport->name, i, ss5port->p_state,ss5port->p_m_s_state);
300 PDEBUG(DEBUG_SS5, "no free interface\n");
307 if (selchannel->channel<1 || selchannel->channel==16)
309 i = selchannel->channel-1-(selchannel->channel>=17);
310 if (i >= mISDNport->b_num)
312 port = mISDNport->b_port[i];
315 if (port->p_type == PORT_TYPE_SS5_IN || port->p_type == PORT_TYPE_SS5_OUT)
316 PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because port not idle type.\n",
318 if (port->p_type != PORT_TYPE_SS5_IDLE)
320 ss5port = (class Pss5 *)port;
321 /* is really idle ? */
322 if (ss5port->p_state == PORT_STATE_IDLE
323 && ss5port->p_m_s_state == SS5_STATE_IDLE)
325 PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because p_state=%d, ss5_state=%d.\n",
326 mISDNport->name, i, ss5port->p_state,ss5port->p_m_s_state);
328 selchannel = selchannel->next;
330 PDEBUG(DEBUG_SS5, "no free interface in channel list\n");
338 Pss5::Pss5(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : PmISDN(type, mISDNport, portname, settings, channel, exclusive, mode)
340 p_callerinfo.itype = (mISDNport->ifport->interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN;
341 p_m_s_state = SS5_STATE_IDLE;
342 p_m_s_signal = SS5_SIGNAL_NULL;
343 p_m_s_dial[0] = '\0';
345 p_m_s_pulsecount = 0;
346 p_m_s_last_digit = ' ';
347 p_m_s_signal_loss = 0;
348 p_m_s_decoder_count = 0;
349 //p_m_s_decoder_buffer;
353 p_m_s_timer_fn = NULL;
355 p_m_s_busy_flash = 0;
356 p_m_s_clear_back = 0;
357 memset(p_m_s_delay_digits, ' ', sizeof(p_m_s_delay_digits));
358 memset(p_m_s_delay_mute, ' ', sizeof(p_m_s_delay_mute));
360 /* turn on signalling receiver */
363 PDEBUG(DEBUG_SS5, "Created new mISDNPort(%s). Currently %d objects use.\n", portname, mISDNport->use);
378 void Pss5::_new_ss5_state(int state, const char *func, int line)
380 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]);
382 p_m_s_signal = SS5_SIGNAL_NULL;
384 void Pss5::_new_ss5_signal(int signal, const char *func, int line)
387 PDEBUG(DEBUG_SS5, "%s(%s:%d): changing SS5 signal state from %s to %s\n", p_name, func, line, ss5_signal_name[p_m_s_signal], ss5_signal_name[signal]);
389 PDEBUG(DEBUG_SS5, "%s(%s:%d): changing SS5 signal state to %s\n", p_name, func, line, ss5_signal_name[signal]);
390 p_m_s_signal = signal;
395 * signalling receiver
397 * this function will be called for every audio received.
399 void Pss5::inband_receive(unsigned char *buffer, int len)
401 int count = 0, tocopy, space;
405 /* how much to copy ? */
406 tocopy = len - count;
407 space = SS5_DECODER_NPOINTS - p_m_s_decoder_count;
409 FATAL("p_m_s_decoder_count overflows\n");
413 memcpy(p_m_s_decoder_buffer+p_m_s_decoder_count, buffer+count, tocopy);
414 p_m_s_decoder_count += tocopy;
416 /* decoder buffer not completely filled ? */
420 /* decode one frame */
421 digit = ss5_decode(p_m_s_decoder_buffer, SS5_DECODER_NPOINTS);
422 p_m_s_decoder_count = 0;
425 if (p_m_s_last_digit != digit && digit != ' ')
426 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]);
429 /* ignore short loss of signal */
430 if (p_m_s_signal_loss) {
433 if (p_m_s_signal_loss >= SS5_TIMER_SIGNAL_LOSS) {
435 PDEBUG(DEBUG_SS5, "%s: signal '%c' lost too long\n", p_name, p_m_s_last_digit);
437 /* long enough, we stop loss-timer */
438 p_m_s_signal_loss = 0;
440 /* not long enough, so we use last signal */
441 p_m_s_signal_loss += SS5_DECODER_NPOINTS;
442 digit = p_m_s_last_digit;
445 /* signal is back, we stop timer and store */
447 PDEBUG(DEBUG_SS5, "%s: signal '%c' lost, but continues with '%c'\n", p_name, p_m_s_last_digit, digit);
449 p_m_s_signal_loss = 0;
450 p_m_s_last_digit = digit;
453 if (p_m_s_last_digit != ' ' && digit == ' ') {
455 PDEBUG(DEBUG_SS5, "%s: signal '%c' lost\n", p_name, p_m_s_last_digit);
457 /* restore last digit until signal is really lost */
458 p_m_s_last_digit = digit;
459 /* starting to loose signal */
460 p_m_s_signal_loss = SS5_DECODER_NPOINTS;
462 /* storing last signal, in case it is lost */
463 p_m_s_last_digit = digit;
468 if ((p_m_mISDNport->ss5 & SS5_FEATURE_SUPPRESS)) {
470 memcpy(p_m_s_delay_mute, p_m_s_delay_mute+1, sizeof(p_m_s_delay_mute)-1);
471 p_m_s_delay_mute[sizeof(p_m_s_delay_mute)-1] = digit;
472 mdigit = p_m_s_delay_mute[0];
475 if (mdigit != 'A' && mdigit != 'B' && mdigit != 'C')
479 if (mdigit == 'A' || mdigit == 'B' || mdigit == 'C')
484 /* delay decoded tones */
485 if ((p_m_mISDNport->ss5 & SS5_FEATURE_DELAY)) {
487 memcpy(p_m_s_delay_digits, p_m_s_delay_digits+1, sizeof(p_m_s_delay_digits)-1);
489 p_m_s_delay_digits[sizeof(p_m_s_delay_digits)-1] = digit;
491 digit = p_m_s_delay_digits[0];
494 /* clear forward is always recognized */
495 if (digit == 'C' && p_m_s_state != SS5_STATE_CLEAR_FORWARD && p_m_s_state != SS5_STATE_RELEASE_GUARD) {
497 case PORT_TYPE_SS5_OUT:
498 PDEBUG(DEBUG_SS5, "%s: received release-guard, waiting for recognition\n", p_name);
500 case PORT_TYPE_SS5_IN:
501 PDEBUG(DEBUG_SS5, "%s: received clear-forward, waiting for recognition\n", p_name);
504 PDEBUG(DEBUG_SS5, "%s: received clear-forward in idle state, waiting for recognition\n", p_name);
507 new_state(PORT_STATE_RELEASE);
508 new_ss5_state(SS5_STATE_RELEASE_GUARD);
509 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
512 switch(p_m_s_state) {
514 /* seizing only recognized in port idle state */
515 if (p_state == PORT_STATE_IDLE) {
519 PDEBUG(DEBUG_SS5, "%s: received seize, waiting for recognition\n", p_name);
520 p_type = PORT_TYPE_SS5_IN;
521 new_ss5_state(SS5_STATE_PROCEED_TO_SEND);
522 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
528 if (p_type != PORT_TYPE_SS5_OUT)
530 PDEBUG(DEBUG_SS5, "%s: received answer, waiting for recognition\n", p_name);
531 new_ss5_state(SS5_STATE_ACK_ANSWER);
532 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
537 if (p_type == PORT_TYPE_SS5_IN) {
538 if ((p_m_mISDNport->ss5 & SS5_FEATURE_BELL)) {
539 new_ss5_state(SS5_STATE_DIAL_IN_PULSE); /* go pulsing state */
540 new_ss5_signal(SS5_SIGNAL_PULSE_OFF); /* we are starting with pulse off */
541 p_m_s_pulsecount = 0; /* init pulse counter */
542 p_m_s_dial[0] = '\0'; /* init dial string */
543 pulse_ind(1); /* also inits recogition timer... */
546 PDEBUG(DEBUG_SS5, "%s: received forward-transfer, waiting for recognition\n", p_name);
547 /* forward transfer on incomming lines */
548 new_ss5_state(SS5_STATE_FORWARD_TRANSFER);
549 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
553 if (p_state == PORT_STATE_CONNECT) {
554 PDEBUG(DEBUG_SS5, "%s: received clear-back, waiting for recognition\n", p_name);
555 new_ss5_state(SS5_STATE_ACK_CLEAR_BACK);
557 PDEBUG(DEBUG_SS5, "%s: received busy-flash, waiting for recognition\n", p_name);
558 new_ss5_state(SS5_STATE_ACK_BUSY_FLASH);
560 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
564 /* dialing only allowed in incomming setup state */
565 if (p_state == PORT_STATE_IN_SETUP) {
566 if (!strchr("1234567890*#abc", digit))
568 PDEBUG(DEBUG_SS5, "%s: received dialing start with '%c'\n", p_name, digit);
569 new_ss5_state(SS5_STATE_DIAL_IN);
570 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
571 p_m_s_dial[0] = '\0';
576 /* sending seizing */
577 case SS5_STATE_SEIZING:
578 switch (p_m_s_signal) {
579 case SS5_SIGNAL_SEND_ON:
580 if (digit == 'A') { /* double seize */
581 PDEBUG(DEBUG_SS5, "%s: received double seizure\n", p_name, digit);
582 double_seizure_ind();
586 PDEBUG(DEBUG_SS5, "%s: received answer to outgoing seize, waiting for recognition\n", p_name);
587 /* set recognition timer */
588 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
592 case SS5_SIGNAL_SEND_ON_RECOG:
593 if (digit != 'B') { /* seize */
594 PDEBUG(DEBUG_SS5, "%s: answer to outgoing seize is gone before recognition\n", p_name);
595 new_ss5_signal(SS5_SIGNAL_SEND_ON);
596 // p_m_s_sample_nr = 0;
600 p_m_s_recog += SS5_DECODER_NPOINTS;
601 if (p_m_s_recog < SS5_TIMER_RECOG_SEIZE)
603 PDEBUG(DEBUG_SS5, "%s: answer to outgoing seize recognized, turning off, waiting for recognition\n", p_name);
604 new_ss5_signal(SS5_SIGNAL_SEND_OFF);
606 case SS5_SIGNAL_SEND_OFF:
609 PDEBUG(DEBUG_SS5, "%s: outgoing seizure is complete, proceeding...\n", p_name);
610 new_ss5_state(SS5_STATE_IDLE);
611 proceed_to_send_ind();
615 /* answer to seize */
616 case SS5_STATE_PROCEED_TO_SEND:
617 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
619 PDEBUG(DEBUG_SS5, "%s: incomming seize is gone before recognition\n", p_name);
620 new_ss5_state(SS5_STATE_IDLE);
621 p_type = PORT_TYPE_SS5_IDLE;
624 p_m_s_recog += SS5_DECODER_NPOINTS;
625 if (p_m_s_recog < SS5_TIMER_RECOG_SEIZE)
627 PDEBUG(DEBUG_SS5, "%s: incomming seize is recognized, responding...\n", p_name);
628 new_ss5_signal(SS5_SIGNAL_RECEIVE);
634 PDEBUG(DEBUG_SS5, "%s: incomming seize is gone after responding\n", p_name);
635 new_ss5_state(SS5_STATE_IDLE);
639 /* sending busy flash / answer / clear-back */
640 case SS5_STATE_BUSY_FLASH:
641 case SS5_STATE_ANSWER:
642 case SS5_STATE_CLEAR_BACK:
643 switch (p_m_s_signal) {
644 case SS5_SIGNAL_SEND_ON:
646 PDEBUG(DEBUG_SS5, "%s: received acknowledge, waiting for recognition\n", p_name);
647 /* set recognition timer */
648 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
652 case SS5_SIGNAL_SEND_ON_RECOG:
654 PDEBUG(DEBUG_SS5, "%s: acknowledge is gone before recognition\n", p_name);
655 new_ss5_signal(SS5_SIGNAL_SEND_ON);
656 // p_m_s_sample_nr = 0;
660 p_m_s_recog += SS5_DECODER_NPOINTS;
661 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
663 PDEBUG(DEBUG_SS5, "%s: acknowledge recognized, turning off, waiting for recognition\n", p_name);
664 new_ss5_signal(SS5_SIGNAL_SEND_OFF);
666 case SS5_SIGNAL_SEND_OFF:
669 PDEBUG(DEBUG_SS5, "%s: outgoing signal is complete\n", p_name);
670 new_ss5_state(SS5_STATE_IDLE);
674 /* answer to busy-flash / clear back */
675 case SS5_STATE_ACK_BUSY_FLASH:
676 case SS5_STATE_ACK_CLEAR_BACK:
677 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
679 PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is gone before recognition\n", p_name);
680 new_ss5_state(SS5_STATE_IDLE);
683 p_m_s_recog += SS5_DECODER_NPOINTS;
684 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
686 PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is recognized, responding...\n", p_name);
687 new_ss5_signal(SS5_SIGNAL_RECEIVE);
693 PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is gone after responding\n", p_name);
694 new_ss5_state(SS5_STATE_IDLE);
695 if (p_m_s_state == SS5_STATE_ACK_BUSY_FLASH)
701 /* answer to answer */
702 case SS5_STATE_ACK_ANSWER:
703 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
705 PDEBUG(DEBUG_SS5, "%s: incomming answer is gone before recognition\n", p_name);
706 new_ss5_state(SS5_STATE_IDLE);
709 p_m_s_recog += SS5_DECODER_NPOINTS;
710 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
712 PDEBUG(DEBUG_SS5, "%s: incomming answer is recognized, responding...\n", p_name);
713 new_ss5_signal(SS5_SIGNAL_RECEIVE);
719 PDEBUG(DEBUG_SS5, "%s: incomming answer is gone after responding\n", p_name);
720 new_ss5_state(SS5_STATE_IDLE);
724 /* sending clear-forward */
725 case SS5_STATE_CLEAR_FORWARD:
726 switch (p_m_s_signal) {
727 case SS5_SIGNAL_SEND_ON:
729 PDEBUG(DEBUG_SS5, "%s: received answer to clear-forward, waiting for recognition\n", p_name);
730 /* set recognition timer */
731 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
735 case SS5_SIGNAL_SEND_ON_RECOG:
737 PDEBUG(DEBUG_SS5, "%s: answer to clear-forward is gone before recognition\n", p_name);
738 new_ss5_signal(SS5_SIGNAL_SEND_ON);
739 // p_m_s_sample_nr = 0;
743 p_m_s_recog += SS5_DECODER_NPOINTS;
744 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
746 PDEBUG(DEBUG_SS5, "%s: answer to clear-forward recognized, turning off, waiting for recognition\n", p_name);
747 new_ss5_signal(SS5_SIGNAL_SEND_OFF);
749 case SS5_SIGNAL_SEND_OFF:
751 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward answer, continue with seize\n", p_name);
752 new_state(PORT_STATE_IDLE);
757 PDEBUG(DEBUG_SS5, "%s: answer to clear-forward is complete\n", p_name);
759 new_ss5_signal(SS5_SIGNAL_DELAY);
760 p_m_s_recog = 0; /* use recog to delay */
761 PDEBUG(DEBUG_SS5, "%s: answer to clear-forward on outgoing interface starting delay to prevent ping-pong\n", p_name);
763 case SS5_SIGNAL_DELAY:
765 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward answer, continue with seize\n", p_name);
766 new_state(PORT_STATE_IDLE);
769 p_m_s_recog += SS5_DECODER_NPOINTS;
770 if (p_m_s_recog < SS5_TIMER_RELEASE_DELAY)
772 PDEBUG(DEBUG_SS5, "%s: delay time over, going idle\n", p_name);
773 new_ss5_state(SS5_STATE_IDLE);
774 new_state(PORT_STATE_IDLE);
775 p_type = PORT_TYPE_SS5_IDLE;
779 /* answer to release-guard*/
780 case SS5_STATE_RELEASE_GUARD:
781 switch (p_m_s_signal) {
782 case SS5_SIGNAL_RECEIVE_RECOG:
784 if (p_type == PORT_TYPE_SS5_OUT)
785 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is gone before recognition\n", p_name);
787 PDEBUG(DEBUG_SS5, "%s: incomming clear forward is gone before recognition\n", p_name);
788 new_ss5_state(SS5_STATE_IDLE);
791 p_m_s_recog += SS5_DECODER_NPOINTS;
792 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
794 if (p_type == PORT_TYPE_SS5_OUT)
795 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is recognized, responding...\n", p_name);
797 PDEBUG(DEBUG_SS5, "%s: incomming clear-forward is recognized, responding...\n", p_name);
798 new_ss5_signal(SS5_SIGNAL_RECEIVE);
802 case SS5_SIGNAL_RECEIVE:
804 || p_m_s_sample_nr < 256) /* small hack to keep answer for at least some time */
808 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward is received\n", p_name);
809 new_state(PORT_STATE_IDLE);
813 /* if clear forward stops right after recognition on the incomming side,
814 * the release guard signal stops and may be too short to be recognized at the outgoing side.
815 * to prevent this, a timer can be started to force a release guard that is long
816 * enough to be recognized on the outgoing side.
817 * this will prevent braking via blueboxing (other tricks may still be possible).
819 if ((p_m_mISDNport->ss5 & SS5_FEATURE_RELEASEGUARDTIMER)
820 && p_m_s_sample_nr < SS5_TIMER_RELEASE_GUARD)
822 if (p_type == PORT_TYPE_SS5_OUT)
823 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is gone after responding\n", p_name);
825 PDEBUG(DEBUG_SS5, "%s: incomming clear-forward is gone after responding\n", p_name);
826 if (p_type == PORT_TYPE_SS5_OUT) {
828 new_ss5_signal(SS5_SIGNAL_DELAY);
829 p_m_s_recog = 0; /* use recog to delay */
830 PDEBUG(DEBUG_SS5, "%s: incomming release-guard on outgoing interface starting delay to prevent ping-pong\n", p_name);
833 new_ss5_state(SS5_STATE_IDLE);
836 case SS5_SIGNAL_DELAY:
838 PDEBUG(DEBUG_SS5, "%s: received seize right after release guard is gone, continue with seize\n", p_name);
839 new_state(PORT_STATE_IDLE);
842 p_m_s_recog += SS5_DECODER_NPOINTS;
843 if (p_m_s_recog < SS5_TIMER_RELEASE_DELAY)
845 PDEBUG(DEBUG_SS5, "%s: delay time over, going idle\n", p_name);
846 new_ss5_state(SS5_STATE_IDLE);
847 new_state(PORT_STATE_IDLE);
848 p_type = PORT_TYPE_SS5_IDLE;
852 /* wait time to recognize forward transfer */
853 case SS5_STATE_FORWARD_TRANSFER:
854 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
856 PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is gone before recognition\n", p_name);
857 new_ss5_state(SS5_STATE_IDLE);
860 p_m_s_recog += SS5_DECODER_NPOINTS;
861 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
863 PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is recognized, responding, if BELL feature was selected...\n", p_name);
864 new_ss5_signal(SS5_SIGNAL_RECEIVE);
872 PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is gone after recognition\n", p_name);
873 new_ss5_state(SS5_STATE_IDLE);
874 forward_transfer_ind();
878 /* dialing is received */
879 case SS5_STATE_DIAL_IN:
880 if (strchr("1234567890*#abc", digit)) {
881 if (p_m_s_signal != SS5_SIGNAL_DIGIT_PAUSE)
883 PDEBUG(DEBUG_SS5, "%s: incomming digit '%c' is recognized\n", p_name, digit);
884 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
887 if (p_m_s_signal != SS5_SIGNAL_DIGIT_ON)
889 PDEBUG(DEBUG_SS5, "%s: incomming digit is gone after recognition\n", p_name);
890 new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
893 case SS5_STATE_DIAL_IN_PULSE:
901 /* something more to decode ? */
910 * this function generates tones and assembles dial string with digits and pause
911 * the result is sent to mISDN. it uses the ss5_encode() function.
912 * except for dialing and forward-transfer, tones are continuous and will not change state.
914 int Pss5::inband_send(unsigned char *buffer, int len)
916 int count = 0; /* sample counter */
921 switch(p_m_s_state) {
922 /* turn off transmitter in idle state */
927 case SS5_STATE_SEIZING:
928 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
929 && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
931 duration = -1; /* continuous */
934 /* how much samples do we have left */
938 tocode = duration - p_m_s_sample_nr;
942 ss5_encode(buffer, tocode, digit, p_m_s_sample_nr);
943 /* increase counters */
944 p_m_s_sample_nr += tocode;
948 if (duration > 0 && p_m_s_sample_nr >= duration) {
949 PDEBUG(DEBUG_SS5, "%s: sending tone '%c' complete, starting delay\n", p_name, digit);
950 if (p_m_s_state == SS5_STATE_DOUBLE_SEIZE) {
951 do_release(CAUSE_NOCHANNEL, LOCATION_BEYOND);
954 new_ss5_state(SS5_STATE_DELAY);
958 /* stop sending if too long */
959 if (duration < 0 && p_m_s_sample_nr >= SS5_TIMER_MAX_SIGNAL) {
960 PDEBUG(DEBUG_SS5, "%s: sending tone '%c' too long, stopping\n", p_name, digit);
966 /* incomming seizing */
967 case SS5_STATE_PROCEED_TO_SEND:
968 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
970 duration = -1; /* continuous */
974 case SS5_STATE_BUSY_FLASH:
975 case SS5_STATE_CLEAR_BACK:
976 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
977 && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
979 duration = -1; /* continuous */
983 case SS5_STATE_ANSWER:
984 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
985 && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
987 duration = -1; /* continuous */
991 case SS5_STATE_ACK_BUSY_FLASH:
992 case SS5_STATE_ACK_ANSWER:
993 case SS5_STATE_ACK_CLEAR_BACK:
994 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
996 duration = -1; /* continuous */
1001 case SS5_STATE_FORWARD_TRANSFER:
1002 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1004 /* only on bell systems continue and acknowledge tone */
1005 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_BELL))
1007 duration = SS5_TIMER_FORWARD;
1012 case SS5_STATE_CLEAR_FORWARD:
1013 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1014 && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1016 duration = -1; /* continuous */
1020 case SS5_STATE_RELEASE_GUARD:
1021 if (p_m_s_signal != SS5_SIGNAL_RECEIVE
1022 && p_m_s_signal != SS5_SIGNAL_DELAY)
1024 /* prevent from sending release guard too long */
1025 if (p_m_s_sample_nr >= SS5_TIMER_RELEASE_MAX)
1027 duration = -1; /* continuous */
1031 case SS5_STATE_DIAL_OUT:
1032 if ((p_m_mISDNport->ss5 & SS5_FEATURE_PULSEDIALING))
1033 count = inband_dial_pulse(buffer, len, count);
1035 count = inband_dial_mf(buffer, len, count);
1039 case SS5_STATE_DELAY:
1040 tosend = len - count;
1041 memset(buffer+count, audio_s16_to_law[0], tosend);
1042 p_m_s_sample_nr += tosend;
1044 if (p_m_s_sample_nr >= SS5_TIMER_AFTER_SIGNAL) {
1045 PDEBUG(DEBUG_SS5, "%s: delay done, ready for next signal\n", p_name);
1046 new_ss5_state(SS5_STATE_IDLE);
1051 case SS5_STATE_DOUBLE_SEIZE:
1052 duration = SS5_TIMER_DOUBLE_SEIZE;
1056 /* nothing to send */
1058 PERROR("inband signalling is turned on, but no signal is processed here.");
1059 new_ss5_state(SS5_STATE_IDLE);
1064 /* return (partly) filled buffer */
1069 int Pss5::inband_dial_mf(unsigned char *buffer, int len, int count)
1077 * p_m_s_dial: digits to be dialed
1078 * p_m_s_digit_i: current digit counter
1079 * p_m_s_signal: current signal state
1080 * p_m_s_sample_nr: current sample number
1083 /* get digit and duration */
1084 digit = p_m_s_dial[p_m_s_digit_i];
1085 if (!digit) { /* if end of string reached */
1086 new_ss5_state(SS5_STATE_DELAY);
1087 p_m_s_sample_nr = 0;
1090 if (p_m_s_signal == SS5_SIGNAL_DIGIT_ON) {
1091 if (!p_m_s_digit_i) // first digit
1092 duration = SS5_TIMER_KP;
1094 duration = SS5_TIMER_DIGIT;
1096 duration = SS5_TIMER_PAUSE;
1098 /* end of digit/pause ? */
1099 if (p_m_s_sample_nr >= duration) {
1100 p_m_s_sample_nr = 0;
1101 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE)
1102 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1104 new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
1109 /* how much samples do we have left */
1110 tosend = len - count;
1111 tocode = duration - p_m_s_sample_nr;
1113 FATAL("sample_nr overrun duration");
1114 if (tosend < tocode)
1116 /* digit or pause */
1117 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE) {
1118 memset(buffer+count, audio_s16_to_law[0], tocode);
1119 // printf("coding pause %d bytes\n", tocode);
1121 ss5_encode(buffer+count, tocode, digit, p_m_s_sample_nr);
1122 // printf("coding digit '%c' %d bytes\n", digit, tocode);
1124 /* increase counters */
1125 p_m_s_sample_nr += tocode;
1127 /* can we take more ? */
1134 int Pss5::inband_dial_pulse(unsigned char *buffer, int len, int count)
1142 * p_m_s_dial: digits to be dialed
1143 * p_m_s_digit_i: current digit counter
1144 * p_m_s_signal: current signal state
1145 * p_m_s_sample_nr: current sample number
1149 digit = p_m_s_dial[p_m_s_digit_i];
1150 if (!digit) { /* if end of string reached */
1151 new_ss5_state(SS5_STATE_DELAY);
1152 p_m_s_sample_nr = 0;
1155 /* convert digit to pulse */
1182 if (p_m_s_signal == SS5_SIGNAL_DIGIT_ON) {
1183 if (p_m_s_pulsecount & 1)
1184 duration = BELL_TIMER_MAKE; /* loop closed */
1186 duration = BELL_TIMER_BREAK; /* loop open, tone */
1188 duration = BELL_TIMER_PAUSE;
1190 /* end of digit/pause ? */
1191 if (p_m_s_sample_nr >= duration) {
1192 p_m_s_sample_nr = 0;
1193 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE) {
1194 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1195 PDEBUG(DEBUG_SS5, "%s: starting pusling digit '%c'\n", p_name, digit);
1197 p_m_s_pulsecount++; /* toggle pulse */
1198 if (!(p_m_s_pulsecount & 1)) {
1199 /* pulse now on again, but if end is reached... */
1200 if (p_m_s_pulsecount == (digit<<1)) {
1201 new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
1202 p_m_s_pulsecount = 0;
1209 /* how much samples do we have left */
1210 tosend = len - count;
1211 tocode = duration - p_m_s_sample_nr;
1213 FATAL("sample_nr overrun duration");
1214 if (tosend < tocode)
1216 /* digit or pause */
1217 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE
1218 || (p_m_s_pulsecount&1)) /* ...or currently on and no pulse */
1219 memset(buffer+count, audio_s16_to_law[0], tocode);
1221 ss5_encode(buffer+count, tocode, 'B', p_m_s_sample_nr);
1222 /* increase counters */
1223 p_m_s_sample_nr += tocode;
1225 /* can we take more ? */
1235 void Pss5::start_signal(int state)
1237 PDEBUG(DEBUG_SS5, "%s: starting singal '%s'\n", p_name, ss5_state_name[state]);
1239 new_ss5_state(state);
1240 if (state == SS5_STATE_DIAL_OUT) {
1242 p_m_s_pulsecount = 0;
1243 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1245 new_ss5_signal(SS5_SIGNAL_SEND_ON);
1247 /* double seize must continue the current seize tone, so don't reset sample_nr */
1248 if (state != SS5_STATE_DOUBLE_SEIZE) {
1249 /* (re)set sound phase to 0 */
1250 p_m_s_sample_nr = 0;
1253 /* turn on inband transmitter */
1259 * handles all indications
1261 void Pss5::seizing_ind(void)
1263 ss5_trace_header(p_m_mISDNport, this, SS5_SEIZING_IND, p_m_b_channel);
1266 new_state(PORT_STATE_IN_SETUP);
1269 void Pss5::digit_ind(char digit)
1272 char string[128] = "", dial[128] = "";
1273 int dash, first_digit, last_was_digit;
1276 SCCAT(p_m_s_dial, digit);
1278 if (p_state == PORT_STATE_IN_SETUP)
1279 new_state(PORT_STATE_IN_OVERLAP);
1281 /* not last digit ? */
1286 dash = 0; /* dash must be used next time */
1289 p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
1290 for (i = 0; p_m_s_dial[i]; i++) {
1291 if (dash || (last_was_digit && (p_m_s_dial[i]<'0' || p_m_s_dial[i]>'9')))
1295 switch(p_m_s_dial[i]) {
1310 SCCAT(string, p_m_s_dial[i]);
1311 SCCAT(dial, p_m_s_dial[i]);
1314 SCAT(string, "C11");
1315 SCCAT(dial, p_m_s_dial[i]);
1319 SCAT(string, "C12");
1320 SCCAT(dial, p_m_s_dial[i]);
1324 SCAT(string, "KP1");
1325 SCCAT(dial, p_m_s_dial[i]);
1329 SCAT(string, "KP2");
1330 SCCAT(dial, p_m_s_dial[i]);
1341 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1342 add_trace("string", NULL, "%s", string);
1343 add_trace("number", NULL, "%s", dial);
1345 new_ss5_state(SS5_STATE_IDLE);
1348 new_state(PORT_STATE_IN_PROCEEDING);
1351 void Pss5::pulse_ind(int on)
1353 struct lcr_msg *message;
1354 char dial[3] = "a.";
1356 if (p_m_s_signal == SS5_SIGNAL_PULSE_OFF) {
1358 /* pulse turns on */
1360 new_ss5_signal(SS5_SIGNAL_PULSE_ON);
1361 /* pulse turns of, count it */
1363 PDEBUG(DEBUG_SS5, "%s: pulse turns on, counting\n", p_name);
1365 /* pulse remains off */
1366 p_m_s_recog += SS5_DECODER_NPOINTS;
1367 /* not recognized end of digit, we wait... */
1368 if (p_m_s_recog < BELL_TIMER_RECOG_END)
1370 PDEBUG(DEBUG_SS5, "%s: pulse remains off, counted %d pulses\n", p_name, p_m_s_pulsecount);
1371 if (p_m_s_pulsecount >= 12)
1373 else if (p_m_s_pulsecount == 11)
1375 else if (p_m_s_pulsecount == 10)
1378 dial[1] = p_m_s_pulsecount + '0';
1379 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1380 add_trace("digit", NULL, "%s", dial+1);
1381 add_trace("pulses", NULL, "%d", p_m_s_pulsecount);
1383 /* special star release feature */
1384 if ((p_m_mISDNport->ss5 & SS5_FEATURE_STAR_RELEASE) && dial[1] == '*') {
1385 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1386 add_trace("star", NULL, "releases call");
1390 if (p_state == PORT_STATE_IN_SETUP) {
1391 /* sending digit as setup */
1392 do_setup(dial); /* include 'a' == KP1 */
1393 new_state(PORT_STATE_IN_OVERLAP);
1395 /* sending digit as information */
1396 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_INFORMATION);
1397 SCPY(message->param.information.id, dial+1);
1398 message_put(message);
1400 new_ss5_state(SS5_STATE_IDLE);
1401 /* done rx pulses, return to idle */
1402 new_ss5_state(SS5_STATE_IDLE);
1406 /* pulse remains on */
1407 p_m_s_recog += SS5_DECODER_NPOINTS;
1409 /* pulse turns off */
1410 if (p_m_s_recog >= BELL_TIMER_RECOG_HANGUP) {
1411 PDEBUG(DEBUG_SS5, "%s: long pulse turns off, releasing\n", p_name);
1412 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1413 add_trace("longtone", NULL, "releases call");
1416 /* long pulse is gone, release current connection, if any */
1417 while(p_epointlist) {
1418 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1419 message->param.disconnectinfo.location = LOCATION_BEYOND;
1420 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1421 message_put(message);
1422 free_epointlist(p_epointlist);
1425 /* return to setup state */
1426 new_state(PORT_STATE_IN_SETUP);
1427 new_ss5_state(SS5_STATE_IDLE);
1430 PDEBUG(DEBUG_SS5, "%s: short pulse turns off, releasing\n", p_name);
1432 new_ss5_signal(SS5_SIGNAL_PULSE_OFF);
1437 void Pss5::proceed_to_send_ind(void)
1439 ss5_trace_header(p_m_mISDNport, this, SS5_PROCEED_TO_SEND_IND, p_m_b_channel);
1442 SCPY(p_m_s_dial, p_dialinginfo.id);
1443 start_signal(SS5_STATE_DIAL_OUT);
1445 new_state(PORT_STATE_OUT_OVERLAP);
1448 void Pss5::busy_flash_ind(void)
1450 struct lcr_msg *message;
1452 ss5_trace_header(p_m_mISDNport, this, SS5_BUSY_FLASH_IND, p_m_b_channel);
1455 /* busy before dialing ? */
1459 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_NODISCONNECT)) {
1460 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DISCONNECT);
1461 message->param.disconnectinfo.location = LOCATION_BEYOND;
1462 message->param.disconnectinfo.cause = CAUSE_BUSY;
1463 message_put(message);
1466 new_state(PORT_STATE_IN_DISCONNECT);
1469 void Pss5::answer_ind(void)
1471 struct lcr_msg *message;
1473 ss5_trace_header(p_m_mISDNport, this, SS5_ANSWER_IND, p_m_b_channel);
1476 /* answer before dialing ? */
1480 /* already connected */
1481 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_CONNECT)) {
1482 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
1483 message_put(message);
1486 new_state(PORT_STATE_CONNECT);
1489 void Pss5::forward_transfer_ind(void)
1491 // struct lcr_msg *message;
1493 ss5_trace_header(p_m_mISDNport, this, SS5_FORWARD_TRANSFER_IND, p_m_b_channel);
1497 /* if BELL flavor bluebox flag is set, use it to seize a new line */
1498 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_BELL))
1501 /* special BELL flavor hack to clear a line and seize a new one */
1502 while(p_epointlist) {
1503 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1504 message->param.disconnectinfo.location = LOCATION_BEYOND;
1505 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1506 message_put(message);
1507 free_epointlist(p_epointlist);
1510 new_state(PORT_STATE_IN_SETUP);
1514 void Pss5::clear_back_ind(void)
1516 struct lcr_msg *message;
1518 ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_BACK_IND, p_m_b_channel);
1525 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_NODISCONNECT)) {
1526 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DISCONNECT);
1527 message->param.disconnectinfo.location = LOCATION_BEYOND;
1528 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1529 message_put(message);
1532 new_state(PORT_STATE_IN_DISCONNECT);
1535 void Pss5::clear_forward_ind(void)
1537 struct lcr_msg *message;
1539 ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_FORWARD_IND, p_m_b_channel);
1542 new_state(PORT_STATE_IDLE);
1544 p_type = PORT_TYPE_SS5_IDLE;
1550 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1551 message->param.disconnectinfo.location = LOCATION_BEYOND;
1552 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1553 message_put(message);
1554 free_epointlist(p_epointlist);
1558 void Pss5::release_guard_ind(void)
1560 struct lcr_msg *message;
1562 ss5_trace_header(p_m_mISDNport, this, SS5_RELEASE_GUARD_IND, p_m_b_channel);
1571 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1572 message->param.disconnectinfo.location = LOCATION_BEYOND;
1573 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1574 message_put(message);
1575 free_epointlist(p_epointlist);
1578 void Pss5::double_seizure_ind(void)
1580 ss5_trace_header(p_m_mISDNport, this, SS5_DOUBLE_SEIZURE_IND, p_m_b_channel);
1582 ss5_trace_header(p_m_mISDNport, this, SS5_DOUBLE_SEIZURE_REQ, p_m_b_channel);
1585 /* start double seizure sequence, so remote exchange will recognize it */
1586 start_signal(SS5_STATE_DOUBLE_SEIZE);
1591 * shuts down by sending a clear forward and releasing endpoint
1593 void Pss5::do_release(int cause, int location)
1595 struct lcr_msg *message;
1597 /* sending release to endpoint */
1598 while(p_epointlist) {
1599 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1600 message->param.disconnectinfo.location = location;
1601 message->param.disconnectinfo.cause = cause;
1602 message_put(message);
1603 free_epointlist(p_epointlist);
1606 /* start clear-forward */
1607 ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_FORWARD_REQ, p_m_b_channel);
1609 start_signal(SS5_STATE_CLEAR_FORWARD);
1611 new_state(PORT_STATE_RELEASE);
1616 * create endpoint and send setup
1618 void Pss5::do_setup(char *dial)
1620 class Endpoint *epoint;
1621 struct lcr_msg *message;
1623 SCPY(p_dialinginfo.id, dial);
1624 p_dialinginfo.sending_complete = 1;
1625 p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
1626 p_callerinfo.screen = INFO_SCREEN_NETWORK;
1627 p_callerinfo.ntype = INFO_NTYPE_NOTPRESENT;
1628 p_callerinfo.isdn_port = p_m_portnum;
1629 SCPY(p_callerinfo.interface, p_m_mISDNport->ifport->interface->name);
1631 p_capainfo.bearer_capa = INFO_BC_AUDIO;
1632 p_capainfo.bearer_info1 = (options.law=='a')?3:2;
1633 p_capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
1634 p_capainfo.hlc = INFO_HLC_NONE;
1635 p_capainfo.exthlc = INFO_HLC_NONE;
1636 p_capainfo.source_mode = B_MODE_TRANSPARENT;
1638 /* create endpoint */
1640 FATAL("Incoming call but already got an endpoint.\n");
1641 if (!(epoint = new Endpoint(p_serial, 0)))
1642 FATAL("No memory for Endpoint instance\n");
1643 if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 0))) //incoming
1644 FATAL("No memory for Endpoint Application instance\n");
1645 epointlist_new(epoint->ep_serial);
1647 /* send setup message to endpoit */
1648 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
1649 message->param.setup.isdn_port = p_m_portnum;
1650 message->param.setup.port_type = p_type;
1651 // message->param.setup.dtmf = !p_m_mISDNport->ifport->nodtmf;
1652 memcpy(&message->param.setup.dialinginfo, &p_dialinginfo, sizeof(struct dialing_info));
1653 memcpy(&message->param.setup.callerinfo, &p_callerinfo, sizeof(struct caller_info));
1654 memcpy(&message->param.setup.redirinfo, &p_redirinfo, sizeof(struct redir_info));
1655 memcpy(&message->param.setup.capainfo, &p_capainfo, sizeof(struct capa_info));
1656 message_put(message);
1664 int Pss5::handler(void)
1668 if ((ret = PmISDN::handler()))
1672 if (p_m_s_timer && p_m_s_timer < now) {
1674 (this->*(p_m_s_timer_fn))();
1677 /* if answer signal is queued */
1678 if (p_m_s_answer && p_m_s_state == SS5_STATE_IDLE) {
1681 ss5_trace_header(p_m_mISDNport, this, SS5_ANSWER_REQ, p_m_b_channel);
1683 start_signal(SS5_STATE_ANSWER);
1686 /* if busy-flash signal is queued */
1687 if (p_m_s_busy_flash && p_m_s_state == SS5_STATE_IDLE) {
1688 p_m_s_busy_flash = 0;
1689 /* start busy-flash */
1690 ss5_trace_header(p_m_mISDNport, this, SS5_BUSY_FLASH_REQ, p_m_b_channel);
1692 start_signal(SS5_STATE_BUSY_FLASH);
1695 /* if clear-back signal is queued */
1696 if (p_m_s_clear_back && p_m_s_state == SS5_STATE_IDLE) {
1697 p_m_s_clear_back = 0;
1698 /* start clear-back */
1699 ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_BACK_REQ, p_m_b_channel);
1701 start_signal(SS5_STATE_CLEAR_BACK);
1709 * handles all messages from endpoint
1713 void Pss5::message_setup(unsigned int epoint_id, int message_id, union parameter *param)
1715 struct lcr_msg *message;
1717 char string[128] = "", dial[128] = "";
1718 int dash, first_digit, last_was_digit;
1721 PERROR("endpoint already exist.\n");
1722 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1723 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1724 message->param.disconnectinfo.cause = CAUSE_UNSPECIFIED;
1725 message_put(message);
1729 /* copy setup infos to port */
1730 memcpy(&p_callerinfo, ¶m->setup.callerinfo, sizeof(p_callerinfo));
1731 memcpy(&p_dialinginfo, ¶m->setup.dialinginfo, sizeof(p_dialinginfo));
1732 memcpy(&p_capainfo, ¶m->setup.capainfo, sizeof(p_capainfo));
1733 memcpy(&p_redirinfo, ¶m->setup.redirinfo, sizeof(p_redirinfo));
1734 /* screen outgoing caller id */
1735 do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_m_mISDNport->ifport->interface);
1736 do_screen(1, p_callerinfo.id2, sizeof(p_callerinfo.id2), &p_callerinfo.ntype2, &p_callerinfo.present2, p_m_mISDNport->ifport->interface);
1738 /* parse dial string */
1739 dash = 0; /* dash must be used next time */
1742 for (i = 0; p_dialinginfo.id[i]; i++) {
1743 if (dash || (last_was_digit && (p_dialinginfo.id[i]<'0' || p_dialinginfo.id[i]>'9')))
1747 switch(p_dialinginfo.id[i]) {
1758 if (i && first_digit)
1762 SCCAT(string, p_dialinginfo.id[i]);
1763 SCCAT(dial, p_dialinginfo.id[i]);
1766 SCAT(string, "C11");
1771 SCAT(string, "C12");
1776 SCAT(string, "KP1");
1781 SCAT(string, "KP2");
1791 if (p_dialinginfo.id[i] != 'P')
1794 if (p_dialinginfo.id[i] == '1') {
1795 SCAT(string, "KP1");
1800 if (p_dialinginfo.id[i] == '2') {
1801 SCAT(string, "KP2");
1809 if (p_dialinginfo.id[i] != '1')
1812 if (p_dialinginfo.id[i] == '1') {
1813 SCAT(string, "C11");
1818 if (p_dialinginfo.id[i] == '2') {
1819 SCAT(string, "C12");
1827 if (p_dialinginfo.id[i] != 'T')
1837 if (dial[0] && dial[strlen(dial)-1] == 'c')
1841 if (dial[0] && dial[strlen(dial)-1]!='c') {
1847 /* error in dial string */
1850 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_REQ, p_m_b_channel);
1851 add_trace("string", NULL, "%s", p_dialinginfo.id);
1853 add_trace("error", NULL, "no number", dial);
1854 else if (dial[0]!='a' && dial[0]!='b')
1855 add_trace("error", NULL, "number must start with KP1/KP2", dial);
1857 add_trace("error", NULL, "illegal format", dial);
1859 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1860 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1861 message->param.disconnectinfo.cause = CAUSE_INVALID;
1862 message_put(message);
1866 /* copy new dial string */
1867 SCPY(p_dialinginfo.id, dial);
1869 /* attach only if not already */
1870 epointlist_new(epoint_id);
1872 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_REQ, p_m_b_channel);
1873 add_trace("string", NULL, "%s", string);
1874 add_trace("type", NULL, "%s", (dial[0]=='b')?"international":"national");
1875 add_trace("number", NULL, "%s", dial);
1877 /* connect auto path */
1878 if ((p_m_mISDNport->ss5 & SS5_FEATURE_CONNECT)) {
1879 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
1880 message_put(message);
1882 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
1883 message_put(message);
1887 ss5_trace_header(p_m_mISDNport, this, SS5_SEIZING_REQ, p_m_b_channel);
1889 new_ss5_state(SS5_STATE_SEIZING);
1890 new_ss5_signal(SS5_SIGNAL_SEND_ON);
1891 p_m_s_sample_nr = 0;
1894 p_type = PORT_TYPE_SS5_OUT;
1895 new_state(PORT_STATE_OUT_SETUP);
1898 /* MESSAGE_CONNECT */
1899 void Pss5::message_connect(unsigned int epoint_id, int message_id, union parameter *param)
1901 memcpy(&p_connectinfo, ¶m->connectinfo, sizeof(p_connectinfo));
1903 if (p_state != PORT_STATE_CONNECT) {
1904 new_state(PORT_STATE_CONNECT);
1911 /* MESSAGE_DISCONNECT */
1912 void Pss5::message_disconnect(unsigned int epoint_id, int message_id, union parameter *param)
1914 /* disconnect and clear forward (release guard) */
1915 // if ((p_type==PORT_TYPE_SS5_IN && !p_m_mISDNport->tones) /* incomming exchange with no tones */
1916 if (0 || p_type==PORT_TYPE_SS5_OUT) { /* outgoing exchange */
1917 do_release(param->disconnectinfo.cause, param->disconnectinfo.location);
1921 ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_BACK_REQ, p_m_b_channel);
1923 start_signal(SS5_STATE_CLEAR_BACK);
1925 new_state(PORT_STATE_OUT_DISCONNECT);
1928 /* MESSAGE_RELEASE */
1929 void Pss5::message_release(unsigned int epoint_id, int message_id, union parameter *param)
1931 do_release(param->disconnectinfo.cause, param->disconnectinfo.location);
1936 * endpoint sends messages to the port
1938 int Pss5::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1940 if (PmISDN::message_epoint(epoint_id, message_id, param))
1943 switch(message_id) {
1944 case MESSAGE_SETUP: /* dial-out command received from epoint */
1945 if (p_state!=PORT_STATE_IDLE) {
1946 PERROR("Pss5(%s) ignoring setup because isdn port is not in idle state (or connected for sending display info).\n", p_name);
1949 if (p_epointlist && p_state==PORT_STATE_IDLE)
1950 FATAL("Pss5(%s): epoint pointer is set in idle state, how bad!!\n", p_name);
1951 message_setup(epoint_id, message_id, param);
1954 case MESSAGE_CONNECT: /* call of endpoint is connected */
1955 message_connect(epoint_id, message_id, param);
1958 case MESSAGE_DISCONNECT: /* call has been disconnected */
1959 message_disconnect(epoint_id, message_id, param);
1962 case MESSAGE_RELEASE: /* release isdn port */
1963 message_release(epoint_id, message_id, param);
1967 PDEBUG(DEBUG_SS5, "Pss5(%s) ss5 port with (caller id %s) received an unhandled message: %d\n", p_name, p_callerinfo.id, message_id);