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 //#define DEBUG_DETECT
40 /* ss5 signal states */
42 SS5_STATE_IDLE, /* no signal */
43 SS5_STATE_SEIZING, /* seizing */
44 SS5_STATE_PROCEED_TO_SEND, /* proceed-to-send */
45 SS5_STATE_BUSY_FLASH, /* busy-flash / clear back */
46 SS5_STATE_ACK_BUSY_FLASH, /* acknowledge of busy/answer/clear-back */
47 SS5_STATE_ANSWER, /* answer */
48 SS5_STATE_ACK_ANSWER, /* acknowledge of busy/answer/clear-back */
49 SS5_STATE_FORWARD_TRANSFER, /* forward transfer */
50 SS5_STATE_CLEAR_BACK, /* clear-back */
51 SS5_STATE_ACK_CLEAR_BACK, /* acknowledge of busy/answer/clear-back */
52 SS5_STATE_CLEAR_FORWARD, /* clear-forward */
53 SS5_STATE_RELEASE_GUARD, /* release-guard */
54 SS5_STATE_DIAL_OUT, /* dialing state (transmitter) */
55 SS5_STATE_DIAL_IN, /* dialing state (receiver) */
56 SS5_STATE_DIAL_IN_PULSE, /* dialing state (receiver with pulses) */
57 SS5_STATE_DELAY, /* after signal wait until next signal can be sent */
58 SS5_STATE_DOUBLE_SEIZE, /* in case of a double seize, we make the remote size recognize it */
60 const char *ss5_state_name[] = {
63 "STATE_PROCEED_TO_SEND",
65 "STATE_ACK_BUSY_FLASH",
68 "STATE_FORWARD_TRANSFER",
70 "STATE_ACK_CLEAR_BACK",
71 "STATE_CLEAR_FORWARD",
72 "STATE_RELEASE_GUARD",
75 "STATE_DIAL_IN_PULSE",
82 /* sending signal states */
83 SS5_SIGNAL_SEND_ON, /* sending signal, waiting for acknowledge */
84 SS5_SIGNAL_SEND_ON_RECOG, /* sending signal, receiving ack, waiting for recogition timer */
85 SS5_SIGNAL_SEND_OFF, /* silence, receiving ack, waiting for stop */
86 /* receiving signal states */
87 SS5_SIGNAL_RECEIVE_RECOG, /* receiving signal, waiting for recognition timer */
88 SS5_SIGNAL_RECEIVE, /* receiving signal / send ack, waiting for stop */
89 SS5_SIGNAL_DELAY, /* delay after release guard to prevent ping-pong */
90 /* sending / receiving digit states */
91 SS5_SIGNAL_DIGIT_PAUSE, /* pausing before sending (next) digit */
92 SS5_SIGNAL_DIGIT_ON, /* sending digit */
93 SS5_SIGNAL_PULSE_OFF, /* make */
94 SS5_SIGNAL_PULSE_ON, /* break */
96 const char *ss5_signal_name[] = {
99 "SIGNAL_SEND_ON_RECOG",
101 "SIGNAL_RECEIVE_RECOG",
104 "SIGNAL_DIGIT_PAUSE",
110 /* ss5 signal timers (in samples) */
111 #define SS5_TIMER_AFTER_SIGNAL (100*8) /* wait after signal is terminated */
112 #define SS5_TIMER_KP (100*8) /* duration of KP1 or KP2 digit */
113 #define SS5_TIMER_DIGIT (55*8) /* duration of all other digits */
114 #define SS5_TIMER_PAUSE (55*8) /* pause between digits */
115 #define SS5_TIMER_FORWARD (850*8) /* forward transfer length */
116 #define SS5_TIMER_RECOG_SEIZE (40*8) /* recognition time of seizing / proceed-to-send signal */
117 #define SS5_TIMER_RECOG_OTHER (125*8) /* recognition time of all other f1/f2 signals */
118 #define SS5_TIMER_SIGNAL_LOSS (15*8) /* minimum time of signal loss for a continous signal */
119 #define SS5_TIMER_DOUBLE_SEIZE (850*8) /* double seize length */
120 #define SS5_TIMER_RELEASE_GUARD (850*8) /* be sure to release after clear-forward */
121 #define SS5_TIMER_RELEASE_MAX (2000*8)/* maximum time for release guard to prevent 'double-releasing' */
122 #define SS5_TIMER_RELEASE_DELAY (4000*8)/* wait after release guard to prevent ping-pong */
123 #define BELL_TIMER_BREAK (50*8) /* loop open, tone */
124 #define BELL_TIMER_MAKE (50*8) /* loop closed, no tone */
125 #define BELL_TIMER_PAUSE (800*8) /* interdigit delay */
126 #define BELL_TIMER_RECOG_HANGUP (200*8) /* time to recognize hangup */
127 #define BELL_TIMER_RECOG_END (300*8) /* recognize end of digit */
130 #define SS5_TIMER_OVERLAP 5.0 /* timeout for overlap digits received on outgoing exchange */
136 enum { /* even values are indications, odd values are requests */
139 SS5_PROCEED_TO_SEND_IND,
140 SS5_PROCEED_TO_SEND_REQ,
147 SS5_CLEAR_FORWARD_IND,
148 SS5_CLEAR_FORWARD_REQ,
149 SS5_RELEASE_GUARD_IND,
150 SS5_RELEASE_GUARD_REQ,
153 SS5_DOUBLE_SEIZURE_IND,
154 SS5_DOUBLE_SEIZURE_REQ,
157 SS5_FORWARD_TRANSFER_IND,
158 SS5_FORWARD_TRANSFER_REQ,
160 static struct isdn_message {
164 {"SEIZING RECEIVED", SS5_SEIZING_IND},
165 {"SEIZING SENDING", SS5_SEIZING_REQ},
166 {"PROCEED-TO-SEND RECEIVED", SS5_PROCEED_TO_SEND_IND},
167 {"PROCEED-TO-SEND SENDING", SS5_PROCEED_TO_SEND_REQ},
168 {"BUSY-FLASH RECEIVED", SS5_BUSY_FLASH_IND},
169 {"BUSY-FLASH SENDING", SS5_BUSY_FLASH_REQ},
170 {"ANSWER RECEIVED", SS5_ANSWER_IND},
171 {"ANSWER SENDING", SS5_ANSWER_REQ},
172 {"CLEAR-BACK RECEIVED", SS5_CLEAR_BACK_IND},
173 {"CLEAR-BACK SENDING", SS5_CLEAR_BACK_REQ},
174 {"CLEAR-FORWARD RECEIVED", SS5_CLEAR_FORWARD_IND},
175 {"CLEAR-FORWARD SENDING", SS5_CLEAR_FORWARD_REQ},
176 {"RELEASE-GUARD RECEIVED", SS5_RELEASE_GUARD_IND},
177 {"RELEASE-GUARD SENDING", SS5_RELEASE_GUARD_REQ},
178 {"ACKNOWLEDGE RECEIVED", SS5_ACKNOWLEDGE_IND},
179 {"ACKNOWLEDGE SENDING", SS5_ACKNOWLEDGE_REQ},
180 {"DOUBLE-SEIZURE RECEIVED", SS5_DOUBLE_SEIZURE_IND},
181 {"DOUBLE-SEIZURE SENDING", SS5_DOUBLE_SEIZURE_REQ},
182 {"DIALING RECEIVED", SS5_DIALING_IND},
183 {"DIALING SENDING", SS5_DIALING_REQ},
184 {"FORWARD-TRANSFER RECEIVED", SS5_FORWARD_TRANSFER_IND},
185 {"FORWARD-TRANSFER SENDING", SS5_FORWARD_TRANSFER_REQ},
188 static void ss5_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int channel)
193 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
194 /* select message and primitive text */
196 while(ss5_message[i].name) {
197 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
198 if (ss5_message[i].value == msg) {
199 SCPY(msgtext, ss5_message[i].name);
205 /* init trace with given values */
206 start_trace(mISDNport?mISDNport->portnum:-1,
207 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
208 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
209 port?port->p_dialinginfo.id:NULL,
210 (msg&1)?DIRECTION_OUT:DIRECTION_IN,
212 port?port->p_serial:0,
214 add_trace("channel", NULL, "%d", channel);
215 switch (port->p_type) {
216 case PORT_TYPE_SS5_OUT:
217 add_trace("state", NULL, "outgoing");
219 case PORT_TYPE_SS5_IN:
220 add_trace("state", NULL, "incomming");
223 add_trace("state", NULL, "idle");
230 * changes release tone into silence
231 * this makes the line sound more authentic
233 void Pss5::set_tone(const char *dir, const char *name)
235 if (name && !strcmp(name, "cause_10"))
238 PmISDN::set_tone(dir, name);
242 * creation of static channels
244 void ss5_create_channel(struct mISDNport *mISDNport, int i)
248 struct port_settings port_settings;
250 SPRINT(portname, "%s-%d", mISDNport->name, i+1);
252 memset(&port_settings, 0, sizeof(port_settings));
253 SCPY(port_settings.tones_dir, options.tones_dir);
255 ss5port = new Pss5(PORT_TYPE_SS5_IDLE, mISDNport, portname, &port_settings, i + (i>=15) + 1, 1, B_MODE_TRANSPARENT);
257 FATAL("No memory for Pss5 class.\n");
258 if (!ss5port->p_m_b_channel)
259 FATAL("No bchannel on given index.\n");
261 /* connect channel */
262 bchannel_event(mISDNport, ss5port->p_m_b_index, B_EVENT_USE);
268 * hunt for a free line
269 * this function returns a port object in idle state.
271 class Pss5 *ss5_hunt_line(struct mISDNport *mISDNport)
275 class Pss5 *ss5port = NULL;
276 struct select_channel *selchannel;
278 PDEBUG(DEBUG_SS5, "Entered name=%s\n", mISDNport->name);
279 selchannel = mISDNport->ifport->out_channel;
281 switch(selchannel->channel) {
282 case CHANNEL_FREE: /* free channel */
283 case CHANNEL_ANY: /* any channel */
284 for (i = 0; i < mISDNport->b_num; i++) {
285 port = mISDNport->b_port[i];
286 PDEBUG(DEBUG_SS5, "Checking port %p on index\n", port, i);
289 if (port->p_type == PORT_TYPE_SS5_IN || port->p_type == PORT_TYPE_SS5_OUT)
290 PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because port not idle type.\n",
292 if (port->p_type != PORT_TYPE_SS5_IDLE)
294 ss5port = (class Pss5 *)port;
295 /* is really idle ? */
296 if (ss5port->p_state == PORT_STATE_IDLE
297 && ss5port->p_m_s_state == SS5_STATE_IDLE)
299 PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because p_state=%d, ss5_state=%d.\n",
300 mISDNport->name, i, ss5port->p_state,ss5port->p_m_s_state);
302 PDEBUG(DEBUG_SS5, "no free interface\n");
309 if (selchannel->channel<1 || selchannel->channel==16)
311 i = selchannel->channel-1-(selchannel->channel>=17);
312 if (i >= mISDNport->b_num)
314 port = mISDNport->b_port[i];
317 if (port->p_type == PORT_TYPE_SS5_IN || port->p_type == PORT_TYPE_SS5_OUT)
318 PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because port not idle type.\n",
320 if (port->p_type != PORT_TYPE_SS5_IDLE)
322 ss5port = (class Pss5 *)port;
323 /* is really idle ? */
324 if (ss5port->p_state == PORT_STATE_IDLE
325 && ss5port->p_m_s_state == SS5_STATE_IDLE)
327 PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because p_state=%d, ss5_state=%d.\n",
328 mISDNport->name, i, ss5port->p_state,ss5port->p_m_s_state);
330 selchannel = selchannel->next;
332 PDEBUG(DEBUG_SS5, "no free interface in channel list\n");
336 int queue_event(struct lcr_work *work, void *instance, int index);
341 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)
343 p_callerinfo.itype = (mISDNport->ifport->interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN;
344 p_m_s_state = SS5_STATE_IDLE;
345 p_m_s_signal = SS5_SIGNAL_NULL;
346 p_m_s_dial[0] = '\0';
348 p_m_s_pulsecount = 0;
349 p_m_s_last_digit = ' ';
350 p_m_s_last_digit_used = ' ';
351 p_m_s_signal_loss = 0;
352 p_m_s_decoder_count = 0;
353 //p_m_s_decoder_buffer;
356 memset(&p_m_s_queue, 0, sizeof(p_m_s_queue));
357 add_work(&p_m_s_queue, queue_event, this, 0);
359 p_m_s_busy_flash = 0;
360 p_m_s_clear_back = 0;
361 memset(p_m_s_delay_digits, ' ', sizeof(p_m_s_delay_digits));
362 memset(p_m_s_delay_mute, ' ', sizeof(p_m_s_delay_mute));
364 /* turn on signalling receiver */
367 PDEBUG(DEBUG_SS5, "Created new mISDNPort(%s). Currently %d objects use.\n", portname, mISDNport->use);
376 del_work(&p_m_s_queue);
383 void Pss5::_new_ss5_state(int state, const char *func, int line)
385 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]);
387 p_m_s_signal = SS5_SIGNAL_NULL;
389 if (p_m_s_state == SS5_STATE_IDLE && (p_m_s_answer || p_m_s_busy_flash || p_m_s_clear_back))
390 trigger_work(&p_m_s_queue);
393 int queue_event(struct lcr_work *work, void *instance, int index)
395 class Pss5 *ss5port = (class Pss5 *)instance;
397 if (ss5port->p_m_s_state == SS5_STATE_IDLE) {
398 /* if answer signal is queued */
399 if (ss5port->p_m_s_answer) {
400 ss5port->p_m_s_answer = 0;
402 ss5_trace_header(ss5port->p_m_mISDNport, ss5port, SS5_ANSWER_REQ, ss5port->p_m_b_channel);
404 ss5port->start_signal(SS5_STATE_ANSWER);
407 /* if busy-flash signal is queued */
408 if (ss5port->p_m_s_busy_flash) {
409 ss5port->p_m_s_busy_flash = 0;
410 /* start busy-flash */
411 ss5_trace_header(ss5port->p_m_mISDNport, ss5port, SS5_BUSY_FLASH_REQ, ss5port->p_m_b_channel);
413 ss5port->start_signal(SS5_STATE_BUSY_FLASH);
416 /* if clear-back signal is queued */
417 if (ss5port->p_m_s_clear_back) {
418 ss5port->p_m_s_clear_back = 0;
419 /* start clear-back */
420 ss5_trace_header(ss5port->p_m_mISDNport, ss5port, SS5_CLEAR_BACK_REQ, ss5port->p_m_b_channel);
422 ss5port->start_signal(SS5_STATE_CLEAR_BACK);
429 void Pss5::_new_ss5_signal(int signal, const char *func, int line)
432 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]);
434 PDEBUG(DEBUG_SS5, "%s(%s:%d): changing SS5 signal state to %s\n", p_name, func, line, ss5_signal_name[signal]);
435 p_m_s_signal = signal;
440 * signalling receiver
442 * this function will be called for every audio received.
444 void Pss5::inband_receive(unsigned char *buffer, int len)
446 int count = 0, tocopy, space;
450 /* how much to copy ? */
451 tocopy = len - count;
452 space = SS5_DECODER_NPOINTS - p_m_s_decoder_count;
454 FATAL("p_m_s_decoder_count overflows\n");
458 memcpy(p_m_s_decoder_buffer+p_m_s_decoder_count, buffer+count, tocopy);
459 p_m_s_decoder_count += tocopy;
461 /* decoder buffer not completely filled ? */
465 /* decode one frame */
466 digit = ss5_decode(p_m_s_decoder_buffer, SS5_DECODER_NPOINTS);
467 p_m_s_decoder_count = 0;
470 if (p_m_s_last_digit != digit && digit != ' ')
471 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]);
474 /* ignore short loss of signal, or change within one decode window */
475 if (p_m_s_signal_loss) {
478 if (p_m_s_signal_loss >= SS5_TIMER_SIGNAL_LOSS) {
480 PDEBUG(DEBUG_SS5, "%s: signal '%c' lost too long\n", p_name, p_m_s_last_digit);
482 /* long enough, we stop loss-timer */
483 p_m_s_signal_loss = 0;
485 /* not long enough, so we use last signal */
486 p_m_s_signal_loss += SS5_DECODER_NPOINTS;
487 digit = p_m_s_last_digit;
490 /* signal is back, we stop timer and store */
492 PDEBUG(DEBUG_SS5, "%s: signal '%c' lost, but continues with '%c'\n", p_name, p_m_s_last_digit, digit);
494 p_m_s_signal_loss = 0;
495 p_m_s_last_digit = digit;
498 if (p_m_s_last_digit != ' ' && digit == ' ') {
500 PDEBUG(DEBUG_SS5, "%s: signal '%c' lost\n", p_name, p_m_s_last_digit);
502 /* restore last digit until signal is really lost */
503 p_m_s_last_digit = digit;
504 /* starting to loose signal */
505 p_m_s_signal_loss = SS5_DECODER_NPOINTS;
506 } else if (digit != p_m_s_last_digit) {
507 /* digit changes, but we keep old digit until it is detected twice */
509 PDEBUG(DEBUG_SS5, "%s: signal '%c' changes to '%c'\n", p_name, p_m_s_last_digit, digit);
511 p_m_s_last_digit = digit;
512 digit = p_m_s_last_digit_used;
514 /* storing last signal, in case it is lost */
515 p_m_s_last_digit = digit;
518 p_m_s_last_digit_used = digit;
521 if ((p_m_mISDNport->ss5 & SS5_FEATURE_SUPPRESS)) {
523 memcpy(p_m_s_delay_mute, p_m_s_delay_mute+1, sizeof(p_m_s_delay_mute)-1);
524 p_m_s_delay_mute[sizeof(p_m_s_delay_mute)-1] = digit;
525 mdigit = p_m_s_delay_mute[0];
528 if (mdigit != 'A' && mdigit != 'B' && mdigit != 'C')
532 if (mdigit == 'A' || mdigit == 'B' || mdigit == 'C')
537 /* delay decoded tones */
538 if ((p_m_mISDNport->ss5 & SS5_FEATURE_DELAY)) {
540 memcpy(p_m_s_delay_digits, p_m_s_delay_digits+1, sizeof(p_m_s_delay_digits)-1);
542 p_m_s_delay_digits[sizeof(p_m_s_delay_digits)-1] = digit;
544 digit = p_m_s_delay_digits[0];
547 /* clear forward is always recognized */
548 if (digit == 'C' && p_m_s_state != SS5_STATE_CLEAR_FORWARD && p_m_s_state != SS5_STATE_RELEASE_GUARD) {
550 case PORT_TYPE_SS5_OUT:
551 PDEBUG(DEBUG_SS5, "%s: received release-guard, waiting for recognition\n", p_name);
553 case PORT_TYPE_SS5_IN:
554 PDEBUG(DEBUG_SS5, "%s: received clear-forward, waiting for recognition\n", p_name);
557 PDEBUG(DEBUG_SS5, "%s: received clear-forward in idle state, waiting for recognition\n", p_name);
560 new_ss5_state(SS5_STATE_RELEASE_GUARD);
561 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
564 switch(p_m_s_state) {
566 /* seizing only recognized in port idle state */
567 if (p_state == PORT_STATE_IDLE) {
571 PDEBUG(DEBUG_SS5, "%s: received seize, waiting for recognition\n", p_name);
572 p_type = PORT_TYPE_SS5_IN;
573 new_ss5_state(SS5_STATE_PROCEED_TO_SEND);
574 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
580 if (p_type != PORT_TYPE_SS5_OUT)
582 PDEBUG(DEBUG_SS5, "%s: received answer, waiting for recognition\n", p_name);
583 new_ss5_state(SS5_STATE_ACK_ANSWER);
584 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
589 if (p_type == PORT_TYPE_SS5_IN) {
590 if ((p_m_mISDNport->ss5 & SS5_FEATURE_BELL)) {
591 new_ss5_state(SS5_STATE_DIAL_IN_PULSE); /* go pulsing state */
592 new_ss5_signal(SS5_SIGNAL_PULSE_OFF); /* we are starting with pulse off */
593 p_m_s_pulsecount = 0; /* init pulse counter */
594 p_m_s_dial[0] = '\0'; /* init dial string */
595 pulse_ind(1); /* also inits recogition timer... */
598 PDEBUG(DEBUG_SS5, "%s: received forward-transfer, waiting for recognition\n", p_name);
599 /* forward transfer on incomming lines */
600 new_ss5_state(SS5_STATE_FORWARD_TRANSFER);
601 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
605 if (p_state == PORT_STATE_CONNECT) {
606 PDEBUG(DEBUG_SS5, "%s: received clear-back, waiting for recognition\n", p_name);
607 new_ss5_state(SS5_STATE_ACK_CLEAR_BACK);
609 PDEBUG(DEBUG_SS5, "%s: received busy-flash, waiting for recognition\n", p_name);
610 new_ss5_state(SS5_STATE_ACK_BUSY_FLASH);
612 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
616 /* dialing only allowed in incomming setup state */
617 if (p_state == PORT_STATE_IN_SETUP) {
618 if (!strchr("1234567890*#abc", digit))
620 PDEBUG(DEBUG_SS5, "%s: received dialing start with '%c'\n", p_name, digit);
621 new_ss5_state(SS5_STATE_DIAL_IN);
622 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
623 p_m_s_dial[0] = '\0';
628 /* sending seizing */
629 case SS5_STATE_SEIZING:
630 switch (p_m_s_signal) {
631 case SS5_SIGNAL_SEND_ON:
632 if (digit == 'A') { /* double seize */
633 PDEBUG(DEBUG_SS5, "%s: received double seizure\n", p_name, digit);
634 double_seizure_ind();
638 PDEBUG(DEBUG_SS5, "%s: received answer to outgoing seize, waiting for recognition\n", p_name);
639 /* set recognition timer */
640 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
644 case SS5_SIGNAL_SEND_ON_RECOG:
645 if (digit != 'B') { /* seize */
646 PDEBUG(DEBUG_SS5, "%s: answer to outgoing seize is gone before recognition\n", p_name);
647 new_ss5_signal(SS5_SIGNAL_SEND_ON);
648 // p_m_s_sample_nr = 0;
652 p_m_s_recog += SS5_DECODER_NPOINTS;
653 if (p_m_s_recog < SS5_TIMER_RECOG_SEIZE)
655 PDEBUG(DEBUG_SS5, "%s: answer to outgoing seize recognized, turning off, waiting for recognition\n", p_name);
656 new_ss5_signal(SS5_SIGNAL_SEND_OFF);
658 case SS5_SIGNAL_SEND_OFF:
661 PDEBUG(DEBUG_SS5, "%s: outgoing seizure is complete, proceeding...\n", p_name);
662 new_ss5_state(SS5_STATE_IDLE);
663 proceed_to_send_ind();
667 /* answer to seize */
668 case SS5_STATE_PROCEED_TO_SEND:
669 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
671 PDEBUG(DEBUG_SS5, "%s: incomming seize is gone before recognition\n", p_name);
672 new_ss5_state(SS5_STATE_IDLE);
673 p_type = PORT_TYPE_SS5_IDLE;
676 p_m_s_recog += SS5_DECODER_NPOINTS;
677 if (p_m_s_recog < SS5_TIMER_RECOG_SEIZE)
679 PDEBUG(DEBUG_SS5, "%s: incomming seize is recognized, responding...\n", p_name);
680 new_ss5_signal(SS5_SIGNAL_RECEIVE);
686 PDEBUG(DEBUG_SS5, "%s: incomming seize is gone after responding\n", p_name);
687 new_ss5_state(SS5_STATE_IDLE);
691 /* sending busy flash / answer / clear-back */
692 case SS5_STATE_BUSY_FLASH:
693 case SS5_STATE_ANSWER:
694 case SS5_STATE_CLEAR_BACK:
695 switch (p_m_s_signal) {
696 case SS5_SIGNAL_SEND_ON:
698 PDEBUG(DEBUG_SS5, "%s: received acknowledge, waiting for recognition\n", p_name);
699 /* set recognition timer */
700 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
704 case SS5_SIGNAL_SEND_ON_RECOG:
706 PDEBUG(DEBUG_SS5, "%s: acknowledge is gone before recognition\n", p_name);
707 new_ss5_signal(SS5_SIGNAL_SEND_ON);
708 // p_m_s_sample_nr = 0;
712 p_m_s_recog += SS5_DECODER_NPOINTS;
713 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
715 PDEBUG(DEBUG_SS5, "%s: acknowledge recognized, turning off, waiting for recognition\n", p_name);
716 new_ss5_signal(SS5_SIGNAL_SEND_OFF);
718 case SS5_SIGNAL_SEND_OFF:
721 PDEBUG(DEBUG_SS5, "%s: outgoing signal is complete\n", p_name);
722 new_ss5_state(SS5_STATE_IDLE);
726 /* answer to busy-flash / clear back */
727 case SS5_STATE_ACK_BUSY_FLASH:
728 case SS5_STATE_ACK_CLEAR_BACK:
729 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
731 PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is gone before recognition\n", p_name);
732 new_ss5_state(SS5_STATE_IDLE);
735 p_m_s_recog += SS5_DECODER_NPOINTS;
736 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
738 PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is recognized, responding...\n", p_name);
739 new_ss5_signal(SS5_SIGNAL_RECEIVE);
745 PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is gone after responding\n", p_name);
746 new_ss5_state(SS5_STATE_IDLE);
747 if (p_m_s_state == SS5_STATE_ACK_BUSY_FLASH)
753 /* answer to answer */
754 case SS5_STATE_ACK_ANSWER:
755 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
757 PDEBUG(DEBUG_SS5, "%s: incomming answer is gone before recognition\n", p_name);
758 new_ss5_state(SS5_STATE_IDLE);
761 p_m_s_recog += SS5_DECODER_NPOINTS;
762 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
764 PDEBUG(DEBUG_SS5, "%s: incomming answer is recognized, responding...\n", p_name);
765 new_ss5_signal(SS5_SIGNAL_RECEIVE);
771 PDEBUG(DEBUG_SS5, "%s: incomming answer is gone after responding\n", p_name);
772 new_ss5_state(SS5_STATE_IDLE);
776 /* sending clear-forward */
777 case SS5_STATE_CLEAR_FORWARD:
778 switch (p_m_s_signal) {
779 case SS5_SIGNAL_SEND_ON:
781 PDEBUG(DEBUG_SS5, "%s: received answer to clear-forward, waiting for recognition\n", p_name);
782 /* set recognition timer */
783 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
787 case SS5_SIGNAL_SEND_ON_RECOG:
789 PDEBUG(DEBUG_SS5, "%s: answer to clear-forward is gone before recognition\n", p_name);
790 new_ss5_signal(SS5_SIGNAL_SEND_ON);
791 // p_m_s_sample_nr = 0;
795 p_m_s_recog += SS5_DECODER_NPOINTS;
796 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
798 PDEBUG(DEBUG_SS5, "%s: answer to clear-forward recognized, turning off, waiting for recognition\n", p_name);
799 new_ss5_signal(SS5_SIGNAL_SEND_OFF);
801 case SS5_SIGNAL_SEND_OFF:
803 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward answer, continue with seize\n", p_name);
804 new_state(PORT_STATE_IDLE);
809 PDEBUG(DEBUG_SS5, "%s: answer to clear-forward is complete\n", p_name);
811 new_ss5_signal(SS5_SIGNAL_DELAY);
812 p_m_s_recog = 0; /* use recog to delay */
813 PDEBUG(DEBUG_SS5, "%s: answer to clear-forward on outgoing interface starting delay to prevent ping-pong\n", p_name);
815 case SS5_SIGNAL_DELAY:
817 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward answer, continue with seize\n", p_name);
818 new_state(PORT_STATE_IDLE);
821 p_m_s_recog += SS5_DECODER_NPOINTS;
822 if (p_m_s_recog < SS5_TIMER_RELEASE_DELAY)
824 PDEBUG(DEBUG_SS5, "%s: delay time over, going idle\n", p_name);
825 new_ss5_state(SS5_STATE_IDLE);
826 new_state(PORT_STATE_IDLE);
827 p_type = PORT_TYPE_SS5_IDLE;
831 /* answer to release-guard*/
832 case SS5_STATE_RELEASE_GUARD:
833 switch (p_m_s_signal) {
834 case SS5_SIGNAL_RECEIVE_RECOG:
836 if (p_type == PORT_TYPE_SS5_OUT)
837 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is gone before recognition\n", p_name);
839 PDEBUG(DEBUG_SS5, "%s: incomming clear forward is gone before recognition\n", p_name);
840 new_ss5_state(SS5_STATE_IDLE);
843 p_m_s_recog += SS5_DECODER_NPOINTS;
844 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
846 if (p_type == PORT_TYPE_SS5_OUT)
847 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is recognized, responding...\n", p_name);
849 PDEBUG(DEBUG_SS5, "%s: incomming clear-forward is recognized, responding...\n", p_name);
850 new_state(PORT_STATE_RELEASE);
851 new_ss5_signal(SS5_SIGNAL_RECEIVE);
855 case SS5_SIGNAL_RECEIVE:
857 || p_m_s_sample_nr < 256) /* small hack to keep answer for at least some time */
861 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward is received\n", p_name);
862 new_state(PORT_STATE_IDLE);
866 /* if clear forward stops right after recognition on the incomming side,
867 * the release guard signal stops and may be too short to be recognized at the outgoing side.
868 * to prevent this, a timer can be started to force a release guard that is long
869 * enough to be recognized on the outgoing side.
870 * this will prevent braking via blueboxing (other tricks may still be possible).
872 if ((p_m_mISDNport->ss5 & SS5_FEATURE_RELEASEGUARDTIMER)
873 && p_m_s_sample_nr < SS5_TIMER_RELEASE_GUARD)
875 if (p_type == PORT_TYPE_SS5_OUT)
876 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is gone after responding\n", p_name);
878 PDEBUG(DEBUG_SS5, "%s: incomming clear-forward is gone after responding\n", p_name);
879 if (p_type == PORT_TYPE_SS5_OUT) {
881 new_ss5_signal(SS5_SIGNAL_DELAY);
882 p_m_s_recog = 0; /* use recog to delay */
883 PDEBUG(DEBUG_SS5, "%s: incomming release-guard on outgoing interface starting delay to prevent ping-pong\n", p_name);
886 new_ss5_state(SS5_STATE_IDLE);
889 case SS5_SIGNAL_DELAY:
891 PDEBUG(DEBUG_SS5, "%s: received seize right after release guard is gone, continue with seize\n", p_name);
892 new_state(PORT_STATE_IDLE);
895 p_m_s_recog += SS5_DECODER_NPOINTS;
896 if (p_m_s_recog < SS5_TIMER_RELEASE_DELAY)
898 PDEBUG(DEBUG_SS5, "%s: delay time over, going idle\n", p_name);
899 new_ss5_state(SS5_STATE_IDLE);
900 new_state(PORT_STATE_IDLE);
901 p_type = PORT_TYPE_SS5_IDLE;
905 /* wait time to recognize forward transfer */
906 case SS5_STATE_FORWARD_TRANSFER:
907 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
909 PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is gone before recognition\n", p_name);
910 new_ss5_state(SS5_STATE_IDLE);
913 p_m_s_recog += SS5_DECODER_NPOINTS;
914 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
916 PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is recognized, responding, if BELL feature was selected...\n", p_name);
917 new_ss5_signal(SS5_SIGNAL_RECEIVE);
925 PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is gone after recognition\n", p_name);
926 new_ss5_state(SS5_STATE_IDLE);
927 forward_transfer_ind();
931 /* dialing is received */
932 case SS5_STATE_DIAL_IN:
933 if (strchr("1234567890*#abc", digit)) {
934 if (p_m_s_signal != SS5_SIGNAL_DIGIT_PAUSE)
936 PDEBUG(DEBUG_SS5, "%s: incomming digit '%c' is recognized\n", p_name, digit);
937 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
940 if (p_m_s_signal != SS5_SIGNAL_DIGIT_ON)
942 PDEBUG(DEBUG_SS5, "%s: incomming digit is gone after recognition\n", p_name);
943 new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
946 case SS5_STATE_DIAL_IN_PULSE:
954 /* something more to decode ? */
963 * this function generates tones and assembles dial string with digits and pause
964 * the result is sent to mISDN. it uses the ss5_encode() function.
965 * except for dialing and forward-transfer, tones are continuous and will not change state.
967 int Pss5::inband_send(unsigned char *buffer, int len)
969 int count = 0; /* sample counter */
974 switch(p_m_s_state) {
975 /* turn off transmitter in idle state */
980 case SS5_STATE_SEIZING:
981 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
982 && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
984 duration = -1; /* continuous */
987 /* how much samples do we have left */
991 tocode = duration - p_m_s_sample_nr;
995 ss5_encode(buffer, tocode, digit, p_m_s_sample_nr);
996 /* increase counters */
997 p_m_s_sample_nr += tocode;
1000 /* more to come ? */
1001 if (duration > 0 && p_m_s_sample_nr >= duration) {
1002 PDEBUG(DEBUG_SS5, "%s: sending tone '%c' complete, starting delay\n", p_name, digit);
1003 if (p_m_s_state == SS5_STATE_DOUBLE_SEIZE) {
1004 do_release(CAUSE_NOCHANNEL, LOCATION_PRIVATE_LOCAL);
1007 new_ss5_state(SS5_STATE_DELAY);
1008 p_m_s_sample_nr = 0;
1011 /* stop sending if too long */
1012 if (duration < 0 && p_m_s_sample_nr >= SS5_TIMER_MAX_SIGNAL) {
1013 PDEBUG(DEBUG_SS5, "%s: sending tone '%c' too long, stopping\n", p_name, digit);
1019 /* incomming seizing */
1020 case SS5_STATE_PROCEED_TO_SEND:
1021 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1023 duration = -1; /* continuous */
1027 case SS5_STATE_BUSY_FLASH:
1028 case SS5_STATE_CLEAR_BACK:
1029 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1030 && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1032 duration = -1; /* continuous */
1036 case SS5_STATE_ANSWER:
1037 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1038 && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1040 duration = -1; /* continuous */
1044 case SS5_STATE_ACK_BUSY_FLASH:
1045 case SS5_STATE_ACK_ANSWER:
1046 case SS5_STATE_ACK_CLEAR_BACK:
1047 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1049 duration = -1; /* continuous */
1054 case SS5_STATE_FORWARD_TRANSFER:
1055 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1057 /* only on bell systems continue and acknowledge tone */
1058 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_BELL))
1060 duration = SS5_TIMER_FORWARD;
1065 case SS5_STATE_CLEAR_FORWARD:
1066 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1067 && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1069 duration = -1; /* continuous */
1073 case SS5_STATE_RELEASE_GUARD:
1074 if (p_m_s_signal != SS5_SIGNAL_RECEIVE
1075 && p_m_s_signal != SS5_SIGNAL_DELAY)
1077 /* prevent from sending release guard too long */
1078 if (p_m_s_sample_nr >= SS5_TIMER_RELEASE_MAX)
1080 duration = -1; /* continuous */
1084 case SS5_STATE_DIAL_OUT:
1085 if ((p_m_mISDNport->ss5 & SS5_FEATURE_PULSEDIALING))
1086 count = inband_dial_pulse(buffer, len, count);
1088 count = inband_dial_mf(buffer, len, count);
1092 case SS5_STATE_DELAY:
1093 tosend = len - count;
1094 memset(buffer+count, audio_s16_to_law[0], tosend);
1095 p_m_s_sample_nr += tosend;
1097 if (p_m_s_sample_nr >= SS5_TIMER_AFTER_SIGNAL) {
1098 PDEBUG(DEBUG_SS5, "%s: delay done, ready for next signal\n", p_name);
1099 new_ss5_state(SS5_STATE_IDLE);
1104 case SS5_STATE_DOUBLE_SEIZE:
1105 duration = SS5_TIMER_DOUBLE_SEIZE;
1109 /* nothing to send */
1111 PERROR("inband signalling is turned on, but no signal is processed here.");
1112 new_ss5_state(SS5_STATE_IDLE);
1117 /* return (partly) filled buffer */
1122 int Pss5::inband_dial_mf(unsigned char *buffer, int len, int count)
1130 * p_m_s_dial: digits to be dialed
1131 * p_m_s_digit_i: current digit counter
1132 * p_m_s_signal: current signal state
1133 * p_m_s_sample_nr: current sample number
1136 /* get digit and duration */
1137 digit = p_m_s_dial[p_m_s_digit_i];
1138 if (!digit) { /* if end of string reached */
1139 new_ss5_state(SS5_STATE_DELAY);
1140 p_m_s_sample_nr = 0;
1143 if (p_m_s_signal == SS5_SIGNAL_DIGIT_ON) {
1144 if (!p_m_s_digit_i) // first digit
1145 duration = SS5_TIMER_KP;
1147 duration = SS5_TIMER_DIGIT;
1149 duration = SS5_TIMER_PAUSE;
1151 /* end of digit/pause ? */
1152 if (p_m_s_sample_nr >= duration) {
1153 p_m_s_sample_nr = 0;
1154 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE)
1155 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1157 new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
1162 /* how much samples do we have left */
1163 tosend = len - count;
1164 tocode = duration - p_m_s_sample_nr;
1166 FATAL("sample_nr overrun duration");
1167 if (tosend < tocode)
1169 /* digit or pause */
1170 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE) {
1171 memset(buffer+count, audio_s16_to_law[0], tocode);
1172 // printf("coding pause %d bytes\n", tocode);
1174 ss5_encode(buffer+count, tocode, digit, p_m_s_sample_nr);
1175 // printf("coding digit '%c' %d bytes\n", digit, tocode);
1177 /* increase counters */
1178 p_m_s_sample_nr += tocode;
1180 /* can we take more ? */
1187 int Pss5::inband_dial_pulse(unsigned char *buffer, int len, int count)
1195 * p_m_s_dial: digits to be dialed
1196 * p_m_s_digit_i: current digit counter
1197 * p_m_s_signal: current signal state
1198 * p_m_s_sample_nr: current sample number
1202 digit = p_m_s_dial[p_m_s_digit_i];
1203 if (!digit) { /* if end of string reached */
1204 new_ss5_state(SS5_STATE_DELAY);
1205 p_m_s_sample_nr = 0;
1208 /* convert digit to pulse */
1235 if (p_m_s_signal == SS5_SIGNAL_DIGIT_ON) {
1236 if (p_m_s_pulsecount & 1)
1237 duration = BELL_TIMER_MAKE; /* loop closed */
1239 duration = BELL_TIMER_BREAK; /* loop open, tone */
1241 duration = BELL_TIMER_PAUSE;
1243 /* end of digit/pause ? */
1244 if (p_m_s_sample_nr >= duration) {
1245 p_m_s_sample_nr = 0;
1246 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE) {
1247 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1248 PDEBUG(DEBUG_SS5, "%s: starting pusling digit '%c'\n", p_name, digit);
1250 p_m_s_pulsecount++; /* toggle pulse */
1251 if (!(p_m_s_pulsecount & 1)) {
1252 /* pulse now on again, but if end is reached... */
1253 if (p_m_s_pulsecount == (digit<<1)) {
1254 new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
1255 p_m_s_pulsecount = 0;
1262 /* how much samples do we have left */
1263 tosend = len - count;
1264 tocode = duration - p_m_s_sample_nr;
1266 FATAL("sample_nr overrun duration");
1267 if (tosend < tocode)
1269 /* digit or pause */
1270 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE
1271 || (p_m_s_pulsecount&1)) /* ...or currently on and no pulse */
1272 memset(buffer+count, audio_s16_to_law[0], tocode);
1274 ss5_encode(buffer+count, tocode, 'B', p_m_s_sample_nr);
1275 /* increase counters */
1276 p_m_s_sample_nr += tocode;
1278 /* can we take more ? */
1288 void Pss5::start_signal(int state)
1290 PDEBUG(DEBUG_SS5, "%s: starting singal '%s'\n", p_name, ss5_state_name[state]);
1292 new_ss5_state(state);
1293 if (state == SS5_STATE_DIAL_OUT) {
1295 p_m_s_pulsecount = 0;
1296 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1298 new_ss5_signal(SS5_SIGNAL_SEND_ON);
1300 /* double seize must continue the current seize tone, so don't reset sample_nr */
1301 if (state != SS5_STATE_DOUBLE_SEIZE) {
1302 /* (re)set sound phase to 0 */
1303 p_m_s_sample_nr = 0;
1306 /* turn on inband transmitter */
1312 * handles all indications
1314 void Pss5::seizing_ind(void)
1316 ss5_trace_header(p_m_mISDNport, this, SS5_SEIZING_IND, p_m_b_channel);
1319 new_state(PORT_STATE_IN_SETUP);
1320 set_tone("", "noise");
1323 void Pss5::digit_ind(char digit)
1326 char string[128] = "", dial[128] = "";
1327 int dash, first_digit, last_was_digit;
1330 SCCAT(p_m_s_dial, digit);
1332 if (p_state == PORT_STATE_IN_SETUP)
1333 new_state(PORT_STATE_IN_OVERLAP);
1335 /* not last digit ? */
1340 dash = 0; /* dash must be used next time */
1343 p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
1344 for (i = 0; p_m_s_dial[i]; i++) {
1345 if (dash || (last_was_digit && (p_m_s_dial[i]<'0' || p_m_s_dial[i]>'9')))
1349 switch(p_m_s_dial[i]) {
1364 SCCAT(string, p_m_s_dial[i]);
1365 SCCAT(dial, p_m_s_dial[i]);
1368 SCAT(string, "C11");
1369 SCCAT(dial, p_m_s_dial[i]);
1373 SCAT(string, "C12");
1374 SCCAT(dial, p_m_s_dial[i]);
1378 SCAT(string, "KP1");
1379 SCCAT(dial, p_m_s_dial[i]);
1383 SCAT(string, "KP2");
1384 SCCAT(dial, p_m_s_dial[i]);
1395 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1396 add_trace("string", NULL, "%s", string);
1397 add_trace("number", NULL, "%s", dial);
1399 new_ss5_state(SS5_STATE_IDLE);
1402 new_state(PORT_STATE_IN_PROCEEDING);
1405 void Pss5::pulse_ind(int on)
1407 struct lcr_msg *message;
1408 char dial[3] = "a.";
1410 if (p_m_s_signal == SS5_SIGNAL_PULSE_OFF) {
1412 /* pulse turns on */
1414 new_ss5_signal(SS5_SIGNAL_PULSE_ON);
1415 /* pulse turns of, count it */
1417 PDEBUG(DEBUG_SS5, "%s: pulse turns on, counting\n", p_name);
1419 /* pulse remains off */
1420 p_m_s_recog += SS5_DECODER_NPOINTS;
1421 /* not recognized end of digit, we wait... */
1422 if (p_m_s_recog < BELL_TIMER_RECOG_END)
1424 PDEBUG(DEBUG_SS5, "%s: pulse remains off, counted %d pulses\n", p_name, p_m_s_pulsecount);
1425 if (p_m_s_pulsecount >= 12)
1427 else if (p_m_s_pulsecount == 11)
1429 else if (p_m_s_pulsecount == 10)
1432 dial[1] = p_m_s_pulsecount + '0';
1433 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1434 add_trace("digit", NULL, "%s", dial+1);
1435 add_trace("pulses", NULL, "%d", p_m_s_pulsecount);
1437 /* special star release feature */
1438 if ((p_m_mISDNport->ss5 & SS5_FEATURE_STAR_RELEASE) && dial[1] == '*') {
1439 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1440 add_trace("star", NULL, "releases call");
1444 if (p_state == PORT_STATE_IN_SETUP) {
1445 /* sending digit as setup */
1446 do_setup(dial, 0); /* include 'a' == KP1 */
1447 new_state(PORT_STATE_IN_OVERLAP);
1449 /* sending digit as information */
1450 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_INFORMATION);
1451 SCPY(message->param.information.id, dial+1);
1452 message_put(message);
1454 new_ss5_state(SS5_STATE_IDLE);
1455 /* done rx pulses, return to idle */
1456 new_ss5_state(SS5_STATE_IDLE);
1460 /* pulse remains on */
1461 p_m_s_recog += SS5_DECODER_NPOINTS;
1463 /* pulse turns off */
1464 if (p_m_s_recog >= BELL_TIMER_RECOG_HANGUP) {
1465 PDEBUG(DEBUG_SS5, "%s: long pulse turns off, releasing\n", p_name);
1466 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1467 add_trace("longtone", NULL, "releases call");
1470 /* long pulse is gone, release current connection, if any */
1471 while(p_epointlist) {
1472 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1473 message->param.disconnectinfo.location = LOCATION_BEYOND;
1474 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1475 message_put(message);
1476 free_epointlist(p_epointlist);
1479 /* return to setup state */
1480 new_state(PORT_STATE_IN_SETUP);
1481 new_ss5_state(SS5_STATE_IDLE);
1484 PDEBUG(DEBUG_SS5, "%s: short pulse turns off, releasing\n", p_name);
1486 new_ss5_signal(SS5_SIGNAL_PULSE_OFF);
1491 void Pss5::proceed_to_send_ind(void)
1493 ss5_trace_header(p_m_mISDNport, this, SS5_PROCEED_TO_SEND_IND, p_m_b_channel);
1496 SCPY(p_m_s_dial, p_dialinginfo.id);
1497 start_signal(SS5_STATE_DIAL_OUT);
1499 new_state(PORT_STATE_OUT_OVERLAP);
1502 void Pss5::busy_flash_ind(void)
1504 struct lcr_msg *message;
1506 ss5_trace_header(p_m_mISDNport, this, SS5_BUSY_FLASH_IND, p_m_b_channel);
1509 /* busy before dialing ? */
1513 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_NODISCONNECT)) {
1514 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DISCONNECT);
1515 message->param.disconnectinfo.location = LOCATION_BEYOND;
1516 message->param.disconnectinfo.cause = CAUSE_BUSY;
1517 message_put(message);
1520 new_state(PORT_STATE_IN_DISCONNECT);
1523 void Pss5::answer_ind(void)
1525 struct lcr_msg *message;
1527 ss5_trace_header(p_m_mISDNport, this, SS5_ANSWER_IND, p_m_b_channel);
1530 /* answer before dialing ? */
1534 /* already connected */
1535 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_CONNECT)) {
1536 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
1537 message_put(message);
1540 new_state(PORT_STATE_CONNECT);
1543 void Pss5::forward_transfer_ind(void)
1545 // struct lcr_msg *message;
1547 ss5_trace_header(p_m_mISDNport, this, SS5_FORWARD_TRANSFER_IND, p_m_b_channel);
1551 /* if BELL flavor bluebox flag is set, use it to seize a new line */
1552 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_BELL))
1555 /* special BELL flavor hack to clear a line and seize a new one */
1556 while(p_epointlist) {
1557 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1558 message->param.disconnectinfo.location = LOCATION_BEYOND;
1559 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1560 message_put(message);
1561 free_epointlist(p_epointlist);
1564 new_state(PORT_STATE_IN_SETUP);
1568 void Pss5::clear_back_ind(void)
1570 struct lcr_msg *message;
1572 ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_BACK_IND, p_m_b_channel);
1579 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_NODISCONNECT)) {
1580 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DISCONNECT);
1581 message->param.disconnectinfo.location = LOCATION_BEYOND;
1582 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1583 message_put(message);
1586 new_state(PORT_STATE_IN_DISCONNECT);
1589 void Pss5::clear_forward_ind(void)
1591 struct lcr_msg *message;
1593 ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_FORWARD_IND, p_m_b_channel);
1596 new_state(PORT_STATE_IDLE);
1598 p_type = PORT_TYPE_SS5_IDLE;
1604 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1605 message->param.disconnectinfo.location = LOCATION_BEYOND;
1606 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1607 message_put(message);
1608 free_epointlist(p_epointlist);
1612 void Pss5::release_guard_ind(void)
1614 struct lcr_msg *message;
1616 ss5_trace_header(p_m_mISDNport, this, SS5_RELEASE_GUARD_IND, p_m_b_channel);
1625 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1626 message->param.disconnectinfo.location = LOCATION_BEYOND;
1627 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1628 message_put(message);
1629 free_epointlist(p_epointlist);
1632 void Pss5::double_seizure_ind(void)
1634 ss5_trace_header(p_m_mISDNport, this, SS5_DOUBLE_SEIZURE_IND, p_m_b_channel);
1636 ss5_trace_header(p_m_mISDNport, this, SS5_DOUBLE_SEIZURE_REQ, p_m_b_channel);
1639 /* start double seizure sequence, so remote exchange will recognize it */
1640 start_signal(SS5_STATE_DOUBLE_SEIZE);
1645 * shuts down by sending a clear forward and releasing endpoint
1647 void Pss5::do_release(int cause, int location)
1649 struct lcr_msg *message;
1651 /* sending release to endpoint */
1652 while(p_epointlist) {
1653 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1654 message->param.disconnectinfo.location = location;
1655 message->param.disconnectinfo.cause = cause;
1656 message_put(message);
1657 free_epointlist(p_epointlist);
1660 /* start clear-forward */
1661 ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_FORWARD_REQ, p_m_b_channel);
1663 start_signal(SS5_STATE_CLEAR_FORWARD);
1665 new_state(PORT_STATE_RELEASE);
1670 * create endpoint and send setup
1672 void Pss5::do_setup(char *dial, int complete)
1674 class Endpoint *epoint;
1675 struct lcr_msg *message;
1677 SCPY(p_dialinginfo.id, dial);
1678 p_dialinginfo.sending_complete = complete;
1679 p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
1680 p_callerinfo.screen = INFO_SCREEN_NETWORK;
1681 p_callerinfo.ntype = INFO_NTYPE_NOTPRESENT;
1682 p_callerinfo.isdn_port = p_m_portnum;
1683 SCPY(p_callerinfo.interface, p_m_mISDNport->ifport->interface->name);
1685 p_capainfo.bearer_capa = INFO_BC_AUDIO;
1686 p_capainfo.bearer_info1 = (options.law=='a')?3:2;
1687 p_capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
1688 p_capainfo.hlc = INFO_HLC_NONE;
1689 p_capainfo.exthlc = INFO_HLC_NONE;
1690 p_capainfo.source_mode = B_MODE_TRANSPARENT;
1692 /* create endpoint */
1694 FATAL("Incoming call but already got an endpoint.\n");
1695 if (!(epoint = new Endpoint(p_serial, 0)))
1696 FATAL("No memory for Endpoint instance\n");
1697 if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 0))) //incoming
1698 FATAL("No memory for Endpoint Application instance\n");
1699 epointlist_new(epoint->ep_serial);
1701 /* send setup message to endpoit */
1702 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
1703 message->param.setup.isdn_port = p_m_portnum;
1704 message->param.setup.port_type = p_type;
1705 // message->param.setup.dtmf = !p_m_mISDNport->ifport->nodtmf;
1706 memcpy(&message->param.setup.dialinginfo, &p_dialinginfo, sizeof(struct dialing_info));
1707 memcpy(&message->param.setup.callerinfo, &p_callerinfo, sizeof(struct caller_info));
1708 memcpy(&message->param.setup.redirinfo, &p_redirinfo, sizeof(struct redir_info));
1709 memcpy(&message->param.setup.capainfo, &p_capainfo, sizeof(struct capa_info));
1710 message_put(message);
1717 * handles all messages from endpoint
1721 void Pss5::message_setup(unsigned int epoint_id, int message_id, union parameter *param)
1723 struct lcr_msg *message;
1725 char string[128] = "", dial[128] = "";
1726 int dash, first_digit, last_was_digit;
1729 PERROR("endpoint already exist.\n");
1730 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1731 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1732 message->param.disconnectinfo.cause = CAUSE_UNSPECIFIED;
1733 message_put(message);
1737 /* copy setup infos to port */
1738 memcpy(&p_callerinfo, ¶m->setup.callerinfo, sizeof(p_callerinfo));
1739 memcpy(&p_dialinginfo, ¶m->setup.dialinginfo, sizeof(p_dialinginfo));
1740 memcpy(&p_capainfo, ¶m->setup.capainfo, sizeof(p_capainfo));
1741 memcpy(&p_redirinfo, ¶m->setup.redirinfo, sizeof(p_redirinfo));
1742 /* screen outgoing caller id */
1743 do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_m_mISDNport->ifport->interface);
1744 do_screen(1, p_callerinfo.id2, sizeof(p_callerinfo.id2), &p_callerinfo.ntype2, &p_callerinfo.present2, p_m_mISDNport->ifport->interface);
1746 /* parse dial string */
1747 dash = 0; /* dash must be used next time */
1750 for (i = 0; p_dialinginfo.id[i]; i++) {
1751 if (dash || (last_was_digit && (p_dialinginfo.id[i]<'0' || p_dialinginfo.id[i]>'9')))
1755 switch(p_dialinginfo.id[i]) {
1766 if (i && first_digit)
1770 SCCAT(string, p_dialinginfo.id[i]);
1771 SCCAT(dial, p_dialinginfo.id[i]);
1774 SCAT(string, "C11");
1779 SCAT(string, "C12");
1784 SCAT(string, "KP1");
1789 SCAT(string, "KP2");
1799 if (p_dialinginfo.id[i] != 'P')
1802 if (p_dialinginfo.id[i] == '1') {
1803 SCAT(string, "KP1");
1808 if (p_dialinginfo.id[i] == '2') {
1809 SCAT(string, "KP2");
1817 if (p_dialinginfo.id[i] != '1')
1820 if (p_dialinginfo.id[i] == '1') {
1821 SCAT(string, "C11");
1826 if (p_dialinginfo.id[i] == '2') {
1827 SCAT(string, "C12");
1835 if (p_dialinginfo.id[i] != 'T')
1845 if (dial[0] && dial[strlen(dial)-1] == 'c')
1849 if (dial[0] && dial[strlen(dial)-1]!='c') {
1855 /* error in dial string */
1858 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_REQ, p_m_b_channel);
1859 add_trace("string", NULL, "%s", p_dialinginfo.id);
1861 add_trace("error", NULL, "no number", dial);
1862 else if (dial[0]!='a' && dial[0]!='b')
1863 add_trace("error", NULL, "number must start with KP1/KP2", dial);
1865 add_trace("error", NULL, "illegal format", dial);
1867 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1868 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1869 message->param.disconnectinfo.cause = CAUSE_INVALID;
1870 message_put(message);
1874 /* copy new dial string */
1875 SCPY(p_dialinginfo.id, dial);
1877 /* attach only if not already */
1878 epointlist_new(epoint_id);
1880 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_REQ, p_m_b_channel);
1881 add_trace("string", NULL, "%s", string);
1882 add_trace("type", NULL, "%s", (dial[0]=='b')?"international":"national");
1883 add_trace("number", NULL, "%s", dial);
1885 /* connect auto path */
1886 if ((p_m_mISDNport->ss5 & SS5_FEATURE_CONNECT)) {
1887 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
1888 message_put(message);
1890 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
1891 message_put(message);
1895 ss5_trace_header(p_m_mISDNport, this, SS5_SEIZING_REQ, p_m_b_channel);
1897 new_ss5_state(SS5_STATE_SEIZING);
1898 new_ss5_signal(SS5_SIGNAL_SEND_ON);
1899 p_m_s_sample_nr = 0;
1902 p_type = PORT_TYPE_SS5_OUT;
1903 new_state(PORT_STATE_OUT_SETUP);
1906 /* MESSAGE_CONNECT */
1907 void Pss5::message_connect(unsigned int epoint_id, int message_id, union parameter *param)
1909 memcpy(&p_connectinfo, ¶m->connectinfo, sizeof(p_connectinfo));
1911 if (p_state != PORT_STATE_CONNECT) {
1912 new_state(PORT_STATE_CONNECT);
1914 trigger_work(&p_m_s_queue);
1920 /* MESSAGE_DISCONNECT */
1921 void Pss5::message_disconnect(unsigned int epoint_id, int message_id, union parameter *param)
1923 /* disconnect and clear forward (release guard) */
1924 // if ((p_type==PORT_TYPE_SS5_IN && !p_m_mISDNport->tones) /* incomming exchange with no tones */
1925 if (0 || p_type==PORT_TYPE_SS5_OUT) { /* outgoing exchange */
1926 do_release(param->disconnectinfo.cause, param->disconnectinfo.location);
1930 ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_BACK_REQ, p_m_b_channel);
1932 start_signal(SS5_STATE_CLEAR_BACK);
1934 new_state(PORT_STATE_OUT_DISCONNECT);
1937 /* MESSAGE_RELEASE */
1938 void Pss5::message_release(unsigned int epoint_id, int message_id, union parameter *param)
1940 do_release(param->disconnectinfo.cause, param->disconnectinfo.location);
1943 void Pss5::register_timeout(void)
1945 do_release(CAUSE_UNSPECIFIED, LOCATION_PRIVATE_LOCAL);
1949 * endpoint sends messages to the port
1951 int Pss5::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1953 if (PmISDN::message_epoint(epoint_id, message_id, param))
1956 switch(message_id) {
1957 case MESSAGE_SETUP: /* dial-out command received from epoint */
1958 if (p_state!=PORT_STATE_IDLE) {
1959 PERROR("Pss5(%s) ignoring setup because isdn port is not in idle state (or connected for sending display info).\n", p_name);
1962 if (p_epointlist && p_state==PORT_STATE_IDLE)
1963 FATAL("Pss5(%s): epoint pointer is set in idle state, how bad!!\n", p_name);
1964 message_setup(epoint_id, message_id, param);
1967 case MESSAGE_CONNECT: /* call of endpoint is connected */
1968 message_connect(epoint_id, message_id, param);
1971 case MESSAGE_DISCONNECT: /* call has been disconnected */
1972 message_disconnect(epoint_id, message_id, param);
1975 case MESSAGE_RELEASE: /* release isdn port */
1976 message_release(epoint_id, message_id, param);
1980 PDEBUG(DEBUG_SS5, "Pss5(%s) ss5 port with (caller id %s) received an unhandled message: %d\n", p_name, p_callerinfo.id, message_id);