chan_lcr: Replaced 'n' (no DTMF) option with 'D' (DTMF)
[lcr.git] / ss5.cpp
1 /*****************************************************************************\
2 **                                                                           **
3 ** LCR                                                                       **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** mISDN ss5                                                                 **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12 /*
13  * STATES:
14  *
15  * there are three types of states
16  *
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
20  *
21  * the port state differs from isdn state:
22  * 
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.
33  *
34  */
35
36 #include "main.h"
37
38 //#define DEBUG_DETECT
39
40 /* ss5 signal states */
41 enum {
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 */
59 };
60 const char *ss5_state_name[] = {
61         "STATE_IDLE",
62         "STATE_SEIZING",
63         "STATE_PROCEED_TO_SEND",
64         "STATE_BUSY_FLASH",
65         "STATE_ACK_BUSY_FLASH",
66         "STATE_ANSWER",
67         "STATE_ACK_ANSWER",
68         "STATE_FORWARD_TRANSFER",
69         "STATE_CLEAR_BACK",
70         "STATE_ACK_CLEAR_BACK",
71         "STATE_CLEAR_FORWARD",
72         "STATE_RELEASE_GUARD",
73         "STATE_DIAL_OUT",
74         "STATE_DIAL_IN",
75         "STATE_DIAL_IN_PULSE",
76         "STATE_DELAY",
77         "STATE_DOUBLE_SEIZE",
78 };
79
80 enum {
81         SS5_SIGNAL_NULL,
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 */
95 };
96 const char *ss5_signal_name[] = {
97         "NULL",
98         "SIGNAL_SEND_ON",
99         "SIGNAL_SEND_ON_RECOG",
100         "SIGNAL_SEND_OFF",
101         "SIGNAL_RECEIVE_RECOG",
102         "SIGNAL_RECEIVE",
103         "SIGNAL_DELAY",
104         "SIGNAL_DIGIT_PAUSE",
105         "SIGNAL_DIGIT_ON",
106         "SIGNAL_PULSE_OFF",
107         "SIGNAL_PULSE_ON",
108 };
109
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 */
128
129 /* ss5 timers */
130 #define SS5_TIMER_OVERLAP       5.0     /* timeout for overlap digits received on outgoing exchange */
131
132
133 /*
134  * ss5 trace header
135  */
136 enum { /* even values are indications, odd values are requests */
137         SS5_SEIZING_IND,
138         SS5_SEIZING_REQ,
139         SS5_PROCEED_TO_SEND_IND,
140         SS5_PROCEED_TO_SEND_REQ,
141         SS5_BUSY_FLASH_IND,
142         SS5_BUSY_FLASH_REQ,
143         SS5_ANSWER_IND,
144         SS5_ANSWER_REQ,
145         SS5_CLEAR_BACK_IND,
146         SS5_CLEAR_BACK_REQ,
147         SS5_CLEAR_FORWARD_IND,
148         SS5_CLEAR_FORWARD_REQ,
149         SS5_RELEASE_GUARD_IND,
150         SS5_RELEASE_GUARD_REQ,
151         SS5_ACKNOWLEDGE_IND,
152         SS5_ACKNOWLEDGE_REQ,
153         SS5_DOUBLE_SEIZURE_IND,
154         SS5_DOUBLE_SEIZURE_REQ,
155         SS5_DIALING_IND,
156         SS5_DIALING_REQ,
157         SS5_FORWARD_TRANSFER_IND,
158         SS5_FORWARD_TRANSFER_REQ,
159 };
160 static struct isdn_message {
161         const char *name;
162         unsigned int value;
163 } ss5_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},
186         {NULL, 0},
187 };
188 static void ss5_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int channel)
189 {
190         int i;
191         char msgtext[64];
192
193         SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
194         /* select message and primitive text */
195         i = 0;
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);
200                         break;
201                 }
202                 i++;
203         }
204
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,
211                     CATEGORY_CH,
212                     port?port->p_serial:0,
213                     msgtext);
214         add_trace("channel", NULL, "%d", channel);
215         switch (port->p_type) {
216                 case PORT_TYPE_SS5_OUT:
217                 add_trace("state", NULL, "outgoing");
218                 break;
219                 case PORT_TYPE_SS5_IN:
220                 add_trace("state", NULL, "incomming");
221                 break;
222                 default:
223                 add_trace("state", NULL, "idle");
224                 break;
225         }
226 }
227
228
229 /*
230  * changes release tone into silence
231  * this makes the line sound more authentic
232  */
233 void Pss5::set_tone(const char *dir, const char *name)
234 {
235         if (name && !strcmp(name, "cause_10"))
236                 name = NULL;
237
238         PmISDN::set_tone(dir, name);
239 }
240
241 /*
242  * creation of static channels
243  */
244 void ss5_create_channel(struct mISDNport *mISDNport, int i)
245 {
246         class Pss5              *ss5port;
247         char                    portname[32];
248         struct port_settings    port_settings;
249
250         SPRINT(portname, "%s-%d", mISDNport->name, i+1);
251
252         memset(&port_settings, 0, sizeof(port_settings));
253         SCPY(port_settings.tones_dir, options.tones_dir);
254
255         ss5port = new Pss5(PORT_TYPE_SS5_IDLE, mISDNport, portname, &port_settings, mISDNport->ifport->interface, i + (i>=15) + 1, 1, B_MODE_TRANSPARENT);
256         if (!ss5port)
257                 FATAL("No memory for Pss5 class.\n");
258         if (!ss5port->p_m_b_channel)
259                 FATAL("No bchannel on given index.\n");
260
261         /* connect channel */
262         bchannel_event(mISDNport, ss5port->p_m_b_index, B_EVENT_USE);
263
264 }
265
266
267 /*
268  * hunt for a free line
269  * this function returns a port object in idle state.
270  */
271 class Pss5 *ss5_hunt_line(struct mISDNport *mISDNport)
272 {
273         int i;
274         class Port      *port;
275         class Pss5      *ss5port = NULL;
276         struct select_channel *selchannel; 
277
278         PDEBUG(DEBUG_SS5, "Entered name=%s\n", mISDNport->name);
279         selchannel = mISDNport->ifport->out_channel;
280         while(selchannel) {
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);
287                                 if (!port)
288                                         continue;
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",
291                                                 mISDNport->name, i);
292                                 if (port->p_type != PORT_TYPE_SS5_IDLE)
293                                         continue;
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)
298                                         return ss5port;
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);
301                         }
302                         PDEBUG(DEBUG_SS5, "no free interface\n");
303                         return NULL;
304
305                         case CHANNEL_NO:
306                         break;
307
308                         default:
309                         if (selchannel->channel<1 || selchannel->channel==16)
310                                 break;
311                         i = selchannel->channel-1-(selchannel->channel>=17);
312                         if (i >= mISDNport->b_num)
313                                 break;
314                         port = mISDNport->b_port[i];
315                         if (!port)
316                                 break;
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",
319                                         mISDNport->name, i);
320                         if (port->p_type != PORT_TYPE_SS5_IDLE)
321                                 break;
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)
326                                 return ss5port;
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);
329                 }
330                 selchannel = selchannel->next;
331         }
332         PDEBUG(DEBUG_SS5, "no free interface in channel list\n");
333         return NULL;
334 }
335
336 int queue_event(struct lcr_work *work, void *instance, int index);
337
338 /*
339  * constructor
340  */
341 Pss5::Pss5(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, struct interface *interface, int channel, int exclusive, int mode) : PmISDN(type, mISDNport, portname, settings, interface, channel, exclusive, mode)
342 {
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';
347         p_m_s_digit_i = 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;
354         p_m_s_sample_nr = 0;
355         p_m_s_recog = 0;
356         memset(&p_m_s_queue, 0, sizeof(p_m_s_queue));
357         add_work(&p_m_s_queue, queue_event, this, 0);
358         p_m_s_answer = 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));
363
364         /* turn on signalling receiver */
365         inband_receive_on();
366
367         PDEBUG(DEBUG_SS5, "Created new mISDNPort(%s). Currently %d objects use.\n", portname, mISDNport->use);
368 }
369
370
371 /*
372  * destructor
373  */
374 Pss5::~Pss5()
375 {
376         del_work(&p_m_s_queue);
377 }
378
379
380 /*
381  * change ss5 states
382  */
383 void Pss5::_new_ss5_state(int state, const char *func, int line)
384 {
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]);
386         p_m_s_state = state;
387         p_m_s_signal = SS5_SIGNAL_NULL;
388
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);
391 }
392
393 int queue_event(struct lcr_work *work, void *instance, int index)
394 {
395         class Pss5 *ss5port = (class Pss5 *)instance;
396
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;
401                         /* start answer */
402                         ss5_trace_header(ss5port->p_m_mISDNport, ss5port, SS5_ANSWER_REQ, ss5port->p_m_b_channel);
403                         end_trace();
404                         ss5port->start_signal(SS5_STATE_ANSWER);
405                 }
406
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);
412                         end_trace();
413                         ss5port->start_signal(SS5_STATE_BUSY_FLASH);
414                 }
415
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);
421                         end_trace();
422                         ss5port->start_signal(SS5_STATE_CLEAR_BACK);
423                 }
424         }
425
426         return 0;
427 }
428
429 void Pss5::_new_ss5_signal(int signal, const char *func, int line)
430 {
431         if (p_m_s_signal)
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]);
433         else
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;
436 }
437
438
439 /*
440  * signalling receiver
441  *
442  * this function will be called for every audio received.
443  */
444 void Pss5::inband_receive(unsigned char *buffer, int len)
445 {
446         int count = 0, tocopy, space;
447         char digit;
448
449         again:
450         /* how much to copy ? */
451         tocopy = len - count;
452         space = SS5_DECODER_NPOINTS - p_m_s_decoder_count;
453         if (space < 0)
454                 FATAL("p_m_s_decoder_count overflows\n");
455         if (space < tocopy)
456                 tocopy = space;
457         /* copy an count */
458         memcpy(p_m_s_decoder_buffer+p_m_s_decoder_count, buffer+count, tocopy);
459         p_m_s_decoder_count += tocopy;
460         count += tocopy;
461         /* decoder buffer not completely filled ? */
462         if (tocopy < space)
463                 return;
464
465         /* decode one frame */
466         digit = ss5_decode(p_m_s_decoder_buffer, SS5_DECODER_NPOINTS);
467         p_m_s_decoder_count = 0;
468
469 #ifdef DEBUG_DETECT
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]);
472 #endif
473
474         /* ignore short loss of signal, or change within one decode window */
475         if (p_m_s_signal_loss) {
476                 if (digit == ' ') {
477                         /* still lost */
478                         if (p_m_s_signal_loss >= SS5_TIMER_SIGNAL_LOSS) {
479 #ifdef DEBUG_DETECT
480                                 PDEBUG(DEBUG_SS5, "%s: signal '%c' lost too long\n", p_name, p_m_s_last_digit);
481 #endif
482                                 /* long enough, we stop loss-timer */
483                                 p_m_s_signal_loss = 0;
484                         } else {
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;
488                         }
489                 } else {
490                         /* signal is back, we stop timer and store */
491 #ifdef DEBUG_DETECT
492                         PDEBUG(DEBUG_SS5, "%s: signal '%c' lost, but continues with '%c'\n", p_name, p_m_s_last_digit, digit);
493 #endif
494                         p_m_s_signal_loss = 0;
495                         p_m_s_last_digit = digit;
496                 }
497         } else {
498                 if (p_m_s_last_digit != ' ' && digit == ' ') {
499 #ifdef DEBUG_DETECT
500                         PDEBUG(DEBUG_SS5, "%s: signal '%c' lost\n", p_name, p_m_s_last_digit);
501 #endif
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 */
508 #ifdef DEBUG_DETECT
509                         PDEBUG(DEBUG_SS5, "%s: signal '%c' changes to '%c'\n", p_name, p_m_s_last_digit, digit);
510 #endif
511                         p_m_s_last_digit = digit;
512                         digit = p_m_s_last_digit_used;
513                 } else {
514                         /* storing last signal, in case it is lost */
515                         p_m_s_last_digit = digit;
516                 }
517         }
518         p_m_s_last_digit_used = digit;
519
520         /* update mute */
521         if ((p_m_mISDNport->ss5 & SS5_FEATURE_SUPPRESS)) {
522                 int mdigit;
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];
526                 if (p_m_mute) {
527                         /* mute is on */
528                         if (mdigit != 'A' && mdigit != 'B' && mdigit != 'C')
529                                 mute_off();
530                 } else {
531                         /* mute is off */
532                         if (mdigit == 'A' || mdigit == 'B' || mdigit == 'C')
533                                 mute_on();
534                 }
535         }
536
537         /* delay decoded tones */
538         if ((p_m_mISDNport->ss5 & SS5_FEATURE_DELAY)) {
539                 /* shift buffer */
540                 memcpy(p_m_s_delay_digits, p_m_s_delay_digits+1, sizeof(p_m_s_delay_digits)-1);
541                 /* first in */
542                 p_m_s_delay_digits[sizeof(p_m_s_delay_digits)-1] = digit;
543                 /* first out */
544                 digit = p_m_s_delay_digits[0];
545         }
546
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) {
549                 switch (p_type) {
550                         case PORT_TYPE_SS5_OUT:
551                         PDEBUG(DEBUG_SS5, "%s: received release-guard, waiting for recognition\n", p_name);
552                         break;
553                         case PORT_TYPE_SS5_IN:
554                         PDEBUG(DEBUG_SS5, "%s: received clear-forward, waiting for recognition\n", p_name);
555                         break;
556                         default:
557                         PDEBUG(DEBUG_SS5, "%s: received clear-forward in idle state, waiting for recognition\n", p_name);
558                         break;
559                 }
560                 new_ss5_state(SS5_STATE_RELEASE_GUARD);
561                 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
562                 p_m_s_recog = 0;
563         } else
564         switch(p_m_s_state) {
565                 case SS5_STATE_IDLE:
566                 /* seizing only recognized in port idle state */
567                 if (p_state == PORT_STATE_IDLE) {
568                         if (digit != 'A')
569                                 break;
570                         seize:
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);
575                         p_m_s_recog = 0;
576                         break;
577                 }
578                 /* other signals */
579                 if (digit == 'A') {
580                         if (p_type != PORT_TYPE_SS5_OUT)
581                                 break;
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);
585                         p_m_s_recog = 0;
586                         break;
587                 }
588                 if (digit == 'B') {
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... */
596                                         break;
597                                 }
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);
602                                 p_m_s_recog = 0;
603                                 break;
604                         }
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);
608                         } else {
609                                 PDEBUG(DEBUG_SS5, "%s: received busy-flash, waiting for recognition\n", p_name);
610                                 new_ss5_state(SS5_STATE_ACK_BUSY_FLASH);
611                         }
612                         new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
613                         p_m_s_recog = 0;
614                         break;
615                 }
616                 /* dialing only allowed in incomming setup state */
617                 if (p_state == PORT_STATE_IN_SETUP) {
618                         if (!strchr("1234567890*#abc", digit))
619                                 break;
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';
624                         digit_ind(digit);
625                         break;
626                 }
627                 break;
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();
635                                 break;
636                         }
637                         if (digit == 'B') {
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);
641                                 p_m_s_recog = 0;
642                         }
643                         break;
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;
649 //                              inband_send_on();
650                                 break;
651                         }
652                         p_m_s_recog += SS5_DECODER_NPOINTS;
653                         if (p_m_s_recog < SS5_TIMER_RECOG_SEIZE)
654                                 break;
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);
657                         break;
658                         case SS5_SIGNAL_SEND_OFF:
659                         if (digit == 'B')
660                                 break;
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();
664                         break;
665                 }
666                 break;
667                 /* answer to seize */
668                 case SS5_STATE_PROCEED_TO_SEND:
669                 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
670                         if (digit != 'A') {
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;
674                                 break;
675                         }
676                         p_m_s_recog += SS5_DECODER_NPOINTS;
677                         if (p_m_s_recog < SS5_TIMER_RECOG_SEIZE)
678                                 break;
679                         PDEBUG(DEBUG_SS5, "%s: incomming seize is recognized, responding...\n", p_name);
680                         new_ss5_signal(SS5_SIGNAL_RECEIVE);
681                         p_m_s_sample_nr = 0;
682                         inband_send_on();
683                         break;
684                 }
685                 if (digit != 'A') {
686                         PDEBUG(DEBUG_SS5, "%s: incomming seize is gone after responding\n", p_name);
687                         new_ss5_state(SS5_STATE_IDLE);
688                         seizing_ind();
689                 }
690                 break;
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:
697                         if (digit == 'A') {
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);
701                                 p_m_s_recog = 0;
702                         }
703                         break;
704                         case SS5_SIGNAL_SEND_ON_RECOG:
705                         if (digit != 'A') {
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;
709 //                              inband_send_on();
710                                 break;
711                         }
712                         p_m_s_recog += SS5_DECODER_NPOINTS;
713                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
714                                 break;
715                         PDEBUG(DEBUG_SS5, "%s: acknowledge recognized, turning off, waiting for recognition\n", p_name);
716                         new_ss5_signal(SS5_SIGNAL_SEND_OFF);
717                         break;
718                         case SS5_SIGNAL_SEND_OFF:
719                         if (digit == 'A')
720                                 break;
721                         PDEBUG(DEBUG_SS5, "%s: outgoing signal is complete\n", p_name);
722                         new_ss5_state(SS5_STATE_IDLE);
723                         break;
724                 }
725                 break;
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) {
730                         if (digit != 'B') {
731                                 PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is gone before recognition\n", p_name);
732                                 new_ss5_state(SS5_STATE_IDLE);
733                                 break;
734                         }
735                         p_m_s_recog += SS5_DECODER_NPOINTS;
736                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
737                                 break;
738                         PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is recognized, responding...\n", p_name);
739                         new_ss5_signal(SS5_SIGNAL_RECEIVE);
740                         p_m_s_sample_nr = 0;
741                         inband_send_on();
742                         break;
743                 }
744                 if (digit != 'B') {
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)
748                                 busy_flash_ind();
749                         else
750                                 clear_back_ind();
751                 }
752                 break;
753                 /* answer to answer */
754                 case SS5_STATE_ACK_ANSWER:
755                 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
756                         if (digit != 'A') {
757                                 PDEBUG(DEBUG_SS5, "%s: incomming answer is gone before recognition\n", p_name);
758                                 new_ss5_state(SS5_STATE_IDLE);
759                                 break;
760                         }
761                         p_m_s_recog += SS5_DECODER_NPOINTS;
762                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
763                                 break;
764                         PDEBUG(DEBUG_SS5, "%s: incomming answer is recognized, responding...\n", p_name);
765                         new_ss5_signal(SS5_SIGNAL_RECEIVE);
766                         p_m_s_sample_nr = 0;
767                         inband_send_on();
768                         break;
769                 }
770                 if (digit != 'A') {
771                         PDEBUG(DEBUG_SS5, "%s: incomming answer is gone after responding\n", p_name);
772                         new_ss5_state(SS5_STATE_IDLE);
773                         answer_ind();
774                 }
775                 break;
776                 /* sending clear-forward */
777                 case SS5_STATE_CLEAR_FORWARD:
778                 switch (p_m_s_signal) {
779                         case SS5_SIGNAL_SEND_ON:
780                         if (digit == 'C') {
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);
784                                 p_m_s_recog = 0;
785                         }
786                         break;
787                         case SS5_SIGNAL_SEND_ON_RECOG:
788                         if (digit != 'C') {
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;
792 //                              inband_send_on();
793                                 break;
794                         }
795                         p_m_s_recog += SS5_DECODER_NPOINTS;
796                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
797                                 break;
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);
800                         break;
801                         case SS5_SIGNAL_SEND_OFF:
802                         if (digit == 'A') {
803                                 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward answer, continue with seize\n", p_name);
804                                 new_state(PORT_STATE_IDLE);
805                                 goto seize;
806                         }
807                         if (digit == 'C')
808                                 break;
809                         PDEBUG(DEBUG_SS5, "%s: answer to clear-forward is complete\n", p_name);
810                         release_guard_ind();
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);
814                         break;
815                         case SS5_SIGNAL_DELAY:
816                         if (digit == 'A') {
817                                 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward answer, continue with seize\n", p_name);
818                                 new_state(PORT_STATE_IDLE);
819                                 goto seize;
820                         }
821                         p_m_s_recog += SS5_DECODER_NPOINTS;
822                         if (p_m_s_recog < SS5_TIMER_RELEASE_DELAY)
823                                 break;
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;
828                         break;
829                 }
830                 break;
831                 /* answer to release-guard*/
832                 case SS5_STATE_RELEASE_GUARD:
833                 switch (p_m_s_signal) {
834                         case SS5_SIGNAL_RECEIVE_RECOG:
835                         if (digit != 'C') {
836                                 if (p_type == PORT_TYPE_SS5_OUT)
837                                         PDEBUG(DEBUG_SS5, "%s: incomming release-guard is gone before recognition\n", p_name);
838                                 else
839                                         PDEBUG(DEBUG_SS5, "%s: incomming clear forward is gone before recognition\n", p_name);
840                                 new_ss5_state(SS5_STATE_IDLE);
841                                 break;
842                         }
843                         p_m_s_recog += SS5_DECODER_NPOINTS;
844                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
845                                 break;
846                         if (p_type == PORT_TYPE_SS5_OUT)
847                                 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is recognized, responding...\n", p_name);
848                         else
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);
852                         p_m_s_sample_nr = 0;
853                         inband_send_on();
854                         break;
855                         case SS5_SIGNAL_RECEIVE:
856                         if (digit == 'C'
857                          || p_m_s_sample_nr < 256) /* small hack to keep answer for at least some time */
858                          break;
859 #if 0
860                         if (digit == 'A') {
861                                 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward is received\n", p_name);
862                                 new_state(PORT_STATE_IDLE);
863                                 goto seize;
864                         }
865 #endif
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).
871                          */
872                         if ((p_m_mISDNport->ss5 & SS5_FEATURE_RELEASEGUARDTIMER)
873                          && p_m_s_sample_nr < SS5_TIMER_RELEASE_GUARD)
874                                 break;
875                         if (p_type == PORT_TYPE_SS5_OUT)
876                                 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is gone after responding\n", p_name);
877                         else
878                                 PDEBUG(DEBUG_SS5, "%s: incomming clear-forward is gone after responding\n", p_name);
879                         if (p_type == PORT_TYPE_SS5_OUT) {
880                                 release_guard_ind();
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);
884                         } else {
885                                 clear_forward_ind();
886                                 new_ss5_state(SS5_STATE_IDLE);
887                         }
888                         break;
889                         case SS5_SIGNAL_DELAY:
890                         if (digit == 'A') {
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);
893                                 goto seize;
894                         }
895                         p_m_s_recog += SS5_DECODER_NPOINTS;
896                         if (p_m_s_recog < SS5_TIMER_RELEASE_DELAY)
897                                 break;
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;
902                         break;
903                 }
904                 break;
905                 /* wait time to recognize forward transfer */
906                 case SS5_STATE_FORWARD_TRANSFER:
907                 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
908                         if (digit != 'B') {
909                                 PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is gone before recognition\n", p_name);
910                                 new_ss5_state(SS5_STATE_IDLE);
911                                 break;
912                         }
913                         p_m_s_recog += SS5_DECODER_NPOINTS;
914                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
915                                 break;
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);
918 #if 0
919                         p_m_s_sample_nr = 0;
920                         inband_send_on();
921 #endif
922                         break;
923                 }
924                 if (digit != 'B') {
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();
928                         break;
929                 }
930                 break;
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)
935                                 break;
936                         PDEBUG(DEBUG_SS5, "%s: incomming digit '%c' is recognized\n", p_name, digit);
937                         new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
938                         digit_ind(digit);
939                 } else {
940                         if (p_m_s_signal != SS5_SIGNAL_DIGIT_ON)
941                                 break;
942                         PDEBUG(DEBUG_SS5, "%s: incomming digit is gone after recognition\n", p_name);
943                         new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
944                 }
945                 break;
946                 case SS5_STATE_DIAL_IN_PULSE:
947                 if (digit == 'B')
948                         pulse_ind(1);
949                 else
950                         pulse_ind(0);
951                 break;
952         }
953
954         /* something more to decode ? */
955         if (count != len)
956                 goto again;
957 }
958
959
960 /*
961  * signalling sender
962  *
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.
966  */
967 int Pss5::inband_send(unsigned char *buffer, int len)
968 {
969         int count = 0; /* sample counter */
970         int duration;
971         char digit;
972         int tocode, tosend;
973
974         switch(p_m_s_state) {
975                 /* turn off transmitter in idle state */
976                 case SS5_STATE_IDLE:
977                 inband_send_off();
978                 break;
979
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)
983                         break;
984                 duration = -1; /* continuous */
985                 digit = 'A';
986                 send:
987                 /* how much samples do we have left */
988                 if (duration < 0)
989                         tocode = len;
990                 else
991                         tocode = duration - p_m_s_sample_nr;
992                 if (tocode > 0) {
993                         if (tocode > len)
994                                 tocode = len;
995                         ss5_encode(buffer, tocode, digit, p_m_s_sample_nr);
996                         /* increase counters */
997                         p_m_s_sample_nr += tocode;
998                         count += tocode;
999                 }
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);
1005                                 break;
1006                         }
1007                         new_ss5_state(SS5_STATE_DELAY);
1008                         p_m_s_sample_nr = 0;
1009                 }
1010 #if 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);
1014                         inband_send_off();
1015                         break;
1016                 }
1017 #endif
1018                 break;
1019                 /* incomming seizing */
1020                 case SS5_STATE_PROCEED_TO_SEND:
1021                 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1022                         break;
1023                 duration = -1; /* continuous */
1024                 digit = 'B';
1025                 goto send;
1026
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)
1031                         break;
1032                 duration = -1; /* continuous */
1033                 digit = 'B';
1034                 goto send;
1035
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)
1039                         break;
1040                 duration = -1; /* continuous */
1041                 digit = 'A';
1042                 goto send;
1043
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)
1048                         break;
1049                 duration = -1; /* continuous */
1050                 digit = 'A';
1051                 goto send;
1052
1053 #if 0
1054                 case SS5_STATE_FORWARD_TRANSFER:
1055                 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1056                         break;
1057                 /* only on bell systems continue and acknowledge tone */
1058                 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_BELL))
1059                         break;
1060                 duration = SS5_TIMER_FORWARD;
1061                 digit = 'B';
1062                 goto send;
1063 #endif
1064
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)
1068                         break;
1069                 duration = -1; /* continuous */
1070                 digit = 'C';
1071                 goto send;
1072
1073                 case SS5_STATE_RELEASE_GUARD:
1074                 if (p_m_s_signal != SS5_SIGNAL_RECEIVE
1075                  && p_m_s_signal != SS5_SIGNAL_DELAY)
1076                         break;
1077                 /* prevent from sending release guard too long */
1078                 if (p_m_s_sample_nr >= SS5_TIMER_RELEASE_MAX)
1079                         break;
1080                 duration = -1; /* continuous */
1081                 digit = 'C';
1082                 goto send;
1083
1084                 case SS5_STATE_DIAL_OUT:
1085                 if ((p_m_mISDNport->ss5 & SS5_FEATURE_PULSEDIALING))
1086                         count = inband_dial_pulse(buffer, len, count);
1087                 else
1088                         count = inband_dial_mf(buffer, len, count);
1089                 break;
1090                 break;
1091
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;
1096                 count += 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);
1100                         inband_send_off();
1101                 }
1102                 break;
1103
1104                 case SS5_STATE_DOUBLE_SEIZE:
1105                 duration = SS5_TIMER_DOUBLE_SEIZE;
1106                 digit = 'A';
1107                 goto send;
1108
1109                 /* nothing to send */
1110                 default:
1111                 PERROR("inband signalling is turned on, but no signal is processed here.");
1112                 new_ss5_state(SS5_STATE_IDLE);
1113                 inband_send_off();
1114                 return 0;
1115         }
1116
1117         /* return (partly) filled buffer */
1118         return count;
1119 }
1120
1121
1122 int Pss5::inband_dial_mf(unsigned char *buffer, int len, int count)
1123 {
1124         int duration;
1125         int tocode, tosend;
1126         char digit;
1127
1128         /* dialing
1129          *
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
1134          */
1135         again:
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;
1141                 return count;
1142         }
1143         if (p_m_s_signal == SS5_SIGNAL_DIGIT_ON) {
1144                 if (!p_m_s_digit_i) // first digit
1145                         duration = SS5_TIMER_KP;
1146                 else
1147                         duration = SS5_TIMER_DIGIT;
1148         } else {
1149                 duration = SS5_TIMER_PAUSE;
1150         }
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);
1156                 else {
1157                         new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
1158                         p_m_s_digit_i++;
1159                         goto again;
1160                 }
1161         }
1162         /* how much samples do we have left */
1163         tosend = len - count;
1164         tocode = duration - p_m_s_sample_nr;
1165         if (tocode < 0)
1166                 FATAL("sample_nr overrun duration");
1167         if (tosend < tocode)
1168                 tocode = tosend;
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);
1173         } else {
1174                 ss5_encode(buffer+count, tocode, digit, p_m_s_sample_nr);
1175 //              printf("coding digit '%c' %d bytes\n", digit, tocode);
1176         }
1177         /* increase counters */
1178         p_m_s_sample_nr += tocode;
1179         count += tocode;
1180         /* can we take more ? */
1181         if (len != count)
1182                 goto again;
1183         return count;
1184 }
1185
1186
1187 int Pss5::inband_dial_pulse(unsigned char *buffer, int len, int count)
1188 {
1189         int tocode, tosend;
1190         int duration;
1191         char digit;
1192
1193         /* dialing
1194          *
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
1199          */
1200         again:
1201         /* get digit */
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;
1206                 return count;
1207         }
1208         /* convert digit to pulse */
1209         switch (digit) {
1210                 case '1':
1211                 case '2':
1212                 case '3':
1213                 case '4':
1214                 case '5':
1215                 case '6':
1216                 case '7':
1217                 case '8':
1218                 case '9':
1219                 digit -= '0';
1220                 break;
1221                 case '0':
1222                 digit = 10;
1223                 break;
1224                 case '*':
1225                 digit = 11;
1226                 break;
1227                 case '#':
1228                 digit = 12;
1229                 break;
1230                 default:
1231                 p_m_s_digit_i++;
1232                 goto again;
1233         }
1234         /* get duration */
1235         if (p_m_s_signal == SS5_SIGNAL_DIGIT_ON) {
1236                 if (p_m_s_pulsecount & 1)
1237                         duration = BELL_TIMER_MAKE; /* loop closed */
1238                 else
1239                         duration = BELL_TIMER_BREAK; /* loop open, tone */
1240         } else {
1241                 duration = BELL_TIMER_PAUSE;
1242         }
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);
1249                 } else {
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;
1256                                         p_m_s_digit_i++;
1257                                         goto again;
1258                                 }
1259                         }
1260                 }
1261         }
1262         /* how much samples do we have left */
1263         tosend = len - count;
1264         tocode = duration - p_m_s_sample_nr;
1265         if (tocode < 0)
1266                 FATAL("sample_nr overrun duration");
1267         if (tosend < tocode)
1268                 tocode = tosend;
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);
1273         else
1274                 ss5_encode(buffer+count, tocode, 'B', p_m_s_sample_nr);
1275         /* increase counters */
1276         p_m_s_sample_nr += tocode;
1277         count += tocode;
1278         /* can we take more ? */
1279         if (len != count)
1280                 goto again;
1281         return count;
1282 }
1283
1284
1285 /*
1286  * start signal
1287  */ 
1288 void Pss5::start_signal(int state)
1289 {
1290         PDEBUG(DEBUG_SS5, "%s: starting singal '%s'\n", p_name, ss5_state_name[state]);
1291         /* start signal */
1292         new_ss5_state(state);
1293         if (state == SS5_STATE_DIAL_OUT) {
1294                 p_m_s_digit_i = 0;
1295                 p_m_s_pulsecount = 0;
1296                 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1297         } else
1298                 new_ss5_signal(SS5_SIGNAL_SEND_ON);
1299
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;
1304         }
1305
1306         /* turn on inband transmitter */
1307         inband_send_on();
1308 }
1309
1310
1311 /*
1312  * handles all indications
1313  */
1314 void Pss5::seizing_ind(void)
1315 {
1316         ss5_trace_header(p_m_mISDNport, this, SS5_SEIZING_IND, p_m_b_channel);
1317         end_trace();
1318
1319         new_state(PORT_STATE_IN_SETUP);
1320         set_tone("", "noise");
1321 }
1322
1323 void Pss5::digit_ind(char digit)
1324 {
1325         int i;
1326         char string[128] = "", dial[128] = "";
1327         int dash, first_digit, last_was_digit;
1328
1329         /* add digit */
1330         SCCAT(p_m_s_dial, digit);
1331
1332         if (p_state == PORT_STATE_IN_SETUP)
1333                 new_state(PORT_STATE_IN_OVERLAP);
1334
1335         /* not last digit ? */
1336         if (digit != 'c')
1337                 return;
1338
1339         /* parse string */
1340         dash = 0; /* dash must be used next time */
1341         first_digit = 1;
1342         last_was_digit = 0;
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')))
1346                         SCCAT(string, '-');
1347                 dash = 0;
1348                 last_was_digit = 0;
1349                 switch(p_m_s_dial[i]) {
1350                         case '1':
1351                         case '2':
1352                         case '3':
1353                         case '4':
1354                         case '5':
1355                         case '6':
1356                         case '7':
1357                         case '8':
1358                         case '9':
1359                         case '0':
1360                         if (first_digit)
1361                                 dash = 1;
1362                         first_digit = 0;
1363                         last_was_digit = 1;
1364                         SCCAT(string, p_m_s_dial[i]);
1365                         SCCAT(dial, p_m_s_dial[i]);
1366                         break;
1367                         case '*':
1368                         SCAT(string, "C11");
1369                         SCCAT(dial, p_m_s_dial[i]);
1370                         dash = 1;
1371                         break;
1372                         case '#':
1373                         SCAT(string, "C12");
1374                         SCCAT(dial, p_m_s_dial[i]);
1375                         dash = 1;
1376                         break;
1377                         case 'a':
1378                         SCAT(string, "KP1");
1379                         SCCAT(dial, p_m_s_dial[i]);
1380                         dash = 1;
1381                         break;
1382                         case 'b':
1383                         SCAT(string, "KP2");
1384                         SCCAT(dial, p_m_s_dial[i]);
1385                         dash = 1;
1386                         break;
1387                         case 'c':
1388                         SCAT(string, "ST");
1389                         dash = 1;
1390                         break;
1391                         default:
1392                         break;
1393                 }
1394         }
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);
1398         end_trace();
1399         new_ss5_state(SS5_STATE_IDLE);
1400
1401         do_setup(dial, 1);
1402         new_state(PORT_STATE_IN_PROCEEDING);
1403 }
1404
1405 void Pss5::pulse_ind(int on)
1406 {
1407         struct lcr_msg *message;
1408         char dial[3] = "a.";
1409
1410         if (p_m_s_signal == SS5_SIGNAL_PULSE_OFF) {
1411                 if (on) {
1412                         /* pulse turns on */
1413                         p_m_s_recog = 0;
1414                         new_ss5_signal(SS5_SIGNAL_PULSE_ON);
1415                         /* pulse turns of, count it */
1416                         p_m_s_pulsecount++;
1417                         PDEBUG(DEBUG_SS5, "%s: pulse turns on, counting\n", p_name);
1418                 } else {
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)
1423                                 return;
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)
1426                                 dial[1] = '#';
1427                         else if (p_m_s_pulsecount == 11)
1428                                 dial[1] = '*';
1429                         else if (p_m_s_pulsecount == 10)
1430                                 dial[1] = '0';
1431                         else
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);
1436                         end_trace();
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");
1441                                 end_trace();
1442                                 goto star_release;
1443                         }
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);
1448                         } else {
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);
1453                         }
1454                                 new_ss5_state(SS5_STATE_IDLE);
1455                         /* done rx pulses, return to idle */
1456                         new_ss5_state(SS5_STATE_IDLE);
1457                 }
1458         } else {
1459                 if (on) {
1460                         /* pulse remains on */
1461                         p_m_s_recog += SS5_DECODER_NPOINTS;
1462                 } else {
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");
1468                                 end_trace();
1469                                 star_release:
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);
1477                                 }
1478                                 set_tone("", NULL);
1479                                 /* return to setup state */
1480                                 new_state(PORT_STATE_IN_SETUP);
1481                                 new_ss5_state(SS5_STATE_IDLE);
1482                                 return;
1483                         }
1484                         PDEBUG(DEBUG_SS5, "%s: short pulse turns off, releasing\n", p_name);
1485                         p_m_s_recog = 0;
1486                         new_ss5_signal(SS5_SIGNAL_PULSE_OFF);
1487                 }
1488         }
1489 }
1490
1491 void Pss5::proceed_to_send_ind(void)
1492 {
1493         ss5_trace_header(p_m_mISDNport, this, SS5_PROCEED_TO_SEND_IND, p_m_b_channel);
1494         end_trace();
1495
1496         SCPY(p_m_s_dial, p_dialinginfo.id);
1497         start_signal(SS5_STATE_DIAL_OUT);
1498
1499         new_state(PORT_STATE_OUT_OVERLAP);
1500 }
1501
1502 void Pss5::busy_flash_ind(void)
1503 {
1504         struct lcr_msg *message;
1505
1506         ss5_trace_header(p_m_mISDNport, this, SS5_BUSY_FLASH_IND, p_m_b_channel);
1507         end_trace();
1508
1509         /* busy before dialing ? */
1510         if (!p_epointlist)
1511                 return;
1512
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);
1518         }
1519
1520         new_state(PORT_STATE_IN_DISCONNECT);
1521 }
1522
1523 void Pss5::answer_ind(void)
1524 {
1525         struct lcr_msg *message;
1526
1527         ss5_trace_header(p_m_mISDNport, this, SS5_ANSWER_IND, p_m_b_channel);
1528         end_trace();
1529
1530         /* answer before dialing ? */
1531         if (!p_epointlist)
1532                 return;
1533
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);
1538         }
1539
1540         new_state(PORT_STATE_CONNECT);
1541 }
1542
1543 void Pss5::forward_transfer_ind(void)
1544 {
1545 //      struct lcr_msg *message;
1546
1547         ss5_trace_header(p_m_mISDNport, this, SS5_FORWARD_TRANSFER_IND, p_m_b_channel);
1548         end_trace();
1549
1550 #if 0
1551         /* if BELL flavor bluebox flag is set, use it to seize a new line */
1552         if (!(p_m_mISDNport->ss5 & SS5_FEATURE_BELL))
1553                 return;
1554
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);
1562         }
1563         set_tone("", NULL);
1564         new_state(PORT_STATE_IN_SETUP);
1565 #endif
1566 }
1567
1568 void Pss5::clear_back_ind(void)
1569 {
1570         struct lcr_msg *message;
1571
1572         ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_BACK_IND, p_m_b_channel);
1573         end_trace();
1574
1575         /* nobody? */
1576         if (!p_epointlist)
1577                 return;
1578
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);
1584         }
1585
1586         new_state(PORT_STATE_IN_DISCONNECT);
1587 }
1588
1589 void Pss5::clear_forward_ind(void)
1590 {
1591         struct lcr_msg *message;
1592
1593         ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_FORWARD_IND, p_m_b_channel);
1594         end_trace();
1595
1596         new_state(PORT_STATE_IDLE);
1597         set_tone("", NULL);
1598         p_type = PORT_TYPE_SS5_IDLE;
1599
1600         /* someone ? */
1601         if (!p_epointlist)
1602                 return;
1603
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);
1609
1610 }
1611
1612 void Pss5::release_guard_ind(void)
1613 {
1614         struct lcr_msg *message;
1615
1616         ss5_trace_header(p_m_mISDNport, this, SS5_RELEASE_GUARD_IND, p_m_b_channel);
1617         end_trace();
1618
1619         set_tone("", NULL);
1620
1621         /* someone ? */
1622         if (!p_epointlist)
1623                 return;
1624
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);
1630 }
1631
1632 void Pss5::double_seizure_ind(void)
1633 {
1634         ss5_trace_header(p_m_mISDNport, this, SS5_DOUBLE_SEIZURE_IND, p_m_b_channel);
1635         end_trace();
1636         ss5_trace_header(p_m_mISDNport, this, SS5_DOUBLE_SEIZURE_REQ, p_m_b_channel);
1637         end_trace();
1638
1639         /* start double seizure sequence, so remote exchange will recognize it */
1640         start_signal(SS5_STATE_DOUBLE_SEIZE);
1641 }
1642
1643
1644 /*
1645  * shuts down by sending a clear forward and releasing endpoint
1646  */
1647 void Pss5::do_release(int cause, int location)
1648 {
1649         struct lcr_msg *message;
1650
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);
1658         }
1659
1660         /* start clear-forward */
1661         ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_FORWARD_REQ, p_m_b_channel);
1662         end_trace();
1663         start_signal(SS5_STATE_CLEAR_FORWARD);
1664
1665         new_state(PORT_STATE_RELEASE);
1666 }
1667
1668
1669 /*
1670  * create endpoint and send setup
1671  */
1672 void Pss5::do_setup(char *dial, int complete)
1673 {
1674         class Endpoint *epoint;
1675         struct lcr_msg *message;
1676
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);
1684
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;
1691
1692         /* create endpoint */
1693         if (p_epointlist)
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         epoint->ep_app = new_endpointapp(epoint, 0, p_m_mISDNport->ifport->interface->app); //incoming
1698         epointlist_new(epoint->ep_serial);
1699
1700         /* send setup message to endpoit */
1701         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
1702         message->param.setup.isdn_port = p_m_portnum;
1703         message->param.setup.port_type = p_type;
1704 //      message->param.setup.dtmf = !p_m_mISDNport->ifport->nodtmf;
1705         memcpy(&message->param.setup.dialinginfo, &p_dialinginfo, sizeof(struct dialing_info));
1706         memcpy(&message->param.setup.callerinfo, &p_callerinfo, sizeof(struct caller_info));
1707         memcpy(&message->param.setup.redirinfo, &p_redirinfo, sizeof(struct redir_info));
1708         memcpy(&message->param.setup.capainfo, &p_capainfo, sizeof(struct capa_info));
1709         message_put(message);
1710
1711 }
1712
1713
1714
1715 /*
1716  * handles all messages from endpoint
1717  */
1718
1719 /* MESSAGE_SETUP */
1720 void Pss5::message_setup(unsigned int epoint_id, int message_id, union parameter *param)
1721 {
1722         struct lcr_msg *message;
1723         int i;
1724         char string[128] = "", dial[128] = "";
1725         int dash, first_digit, last_was_digit;
1726
1727         if (p_epointlist) {
1728                 PERROR("endpoint already exist.\n");
1729                 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1730                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1731                 message->param.disconnectinfo.cause = CAUSE_UNSPECIFIED;
1732                 message_put(message);
1733                 return;
1734         }
1735
1736         /* copy setup infos to port */
1737         memcpy(&p_callerinfo, &param->setup.callerinfo, sizeof(p_callerinfo));
1738         memcpy(&p_dialinginfo, &param->setup.dialinginfo, sizeof(p_dialinginfo));
1739         memcpy(&p_capainfo, &param->setup.capainfo, sizeof(p_capainfo));
1740         memcpy(&p_redirinfo, &param->setup.redirinfo, sizeof(p_redirinfo));
1741         /* screen outgoing caller id */
1742         do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_m_mISDNport->ifport->interface->name);
1743         do_screen(1, p_callerinfo.id2, sizeof(p_callerinfo.id2), &p_callerinfo.ntype2, &p_callerinfo.present2, p_m_mISDNport->ifport->interface->name);
1744
1745         /* parse dial string  */
1746         dash = 0; /* dash must be used next time */
1747         first_digit = 1;
1748         last_was_digit = 0;
1749         for (i = 0; p_dialinginfo.id[i]; i++) {
1750                 if (dash || (last_was_digit && (p_dialinginfo.id[i]<'0' || p_dialinginfo.id[i]>'9')))
1751                         SCCAT(string, '-');
1752                 dash = 0;
1753                 last_was_digit = 0;
1754                 switch(p_dialinginfo.id[i]) {
1755                         case '1':
1756                         case '2':
1757                         case '3':
1758                         case '4':
1759                         case '5':
1760                         case '6':
1761                         case '7':
1762                         case '8':
1763                         case '9':
1764                         case '0':
1765                         if (i && first_digit)
1766                                 dash = 1;
1767                         first_digit = 0;
1768                         last_was_digit = 1;
1769                         SCCAT(string, p_dialinginfo.id[i]);
1770                         SCCAT(dial, p_dialinginfo.id[i]);
1771                         break;
1772                         case '*':
1773                         SCAT(string, "C11");
1774                         SCCAT(dial, '*');
1775                         dash = 1;
1776                         break;
1777                         case '#':
1778                         SCAT(string, "C12");
1779                         SCCAT(dial, '#');
1780                         dash = 1;
1781                         break;
1782                         case 'a':
1783                         SCAT(string, "KP1");
1784                         SCCAT(dial, 'a');
1785                         dash = 1;
1786                         break;
1787                         case 'b':
1788                         SCAT(string, "KP2");
1789                         SCCAT(dial, 'b');
1790                         dash = 1;
1791                         break;
1792                         case 'c':
1793                         SCAT(string, "ST");
1794                         SCCAT(dial, 'c');
1795                         dash = 1;
1796                         case 'K':
1797                         i++;
1798                         if (p_dialinginfo.id[i] != 'P')
1799                                 goto dial_error;
1800                         i++;
1801                         if (p_dialinginfo.id[i] == '1') {
1802                                 SCAT(string, "KP1");
1803                                 SCCAT(dial, 'a');
1804                                 dash = 1;
1805                                 break;
1806                         }
1807                         if (p_dialinginfo.id[i] == '2') {
1808                                 SCAT(string, "KP2");
1809                                 SCCAT(dial, 'b');
1810                                 dash = 1;
1811                                 break;
1812                         }
1813                         goto dial_error;
1814                         case 'C':
1815                         i++;
1816                         if (p_dialinginfo.id[i] != '1')
1817                                 goto dial_error;
1818                         i++;
1819                         if (p_dialinginfo.id[i] == '1') {
1820                                 SCAT(string, "C11");
1821                                 SCCAT(dial, 'a');
1822                                 dash = 1;
1823                                 break;
1824                         }
1825                         if (p_dialinginfo.id[i] == '2') {
1826                                 SCAT(string, "C12");
1827                                 SCCAT(dial, 'b');
1828                                 dash = 1;
1829                                 break;
1830                         }
1831                         goto dial_error;
1832                         case 'S':
1833                         i++;
1834                         if (p_dialinginfo.id[i] != 'T')
1835                                 goto dial_error;
1836                         SCAT(string, "ST");
1837                         SCCAT(dial, 'c');
1838                         dash = 1;
1839                         break;
1840                         default:
1841                         break;
1842                 }
1843                 /* stop, if ST */
1844                 if (dial[0] && dial[strlen(dial)-1] == 'c')
1845                         break;
1846         }
1847         /* terminate */
1848         if (dial[0] && dial[strlen(dial)-1]!='c') {
1849                 SCCAT(string, '-');
1850                 SCAT(string, "ST");
1851                 SCCAT(dial, 'c');
1852         }
1853
1854         /* error in dial string */
1855         if (!dial[0]) {
1856                 dial_error:
1857                 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_REQ, p_m_b_channel);
1858                 add_trace("string", NULL, "%s", p_dialinginfo.id);
1859                 if (!dial[0])
1860                         add_trace("error", NULL, "no number", dial);
1861                 else if (dial[0]!='a' && dial[0]!='b')
1862                         add_trace("error", NULL, "number must start with KP1/KP2", dial);
1863                 else
1864                         add_trace("error", NULL, "illegal format", dial);
1865                 end_trace();
1866                 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1867                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1868                 message->param.disconnectinfo.cause = CAUSE_INVALID;
1869                 message_put(message);
1870                 return;
1871         }
1872
1873         /* copy new dial string */
1874         SCPY(p_dialinginfo.id, dial);
1875
1876         /* attach only if not already */
1877         epointlist_new(epoint_id);
1878
1879         ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_REQ, p_m_b_channel);
1880         add_trace("string", NULL, "%s", string);
1881         add_trace("type", NULL, "%s", (dial[0]=='b')?"international":"national");
1882         add_trace("number", NULL, "%s", dial);
1883         end_trace();
1884         /* connect auto path */
1885         if ((p_m_mISDNport->ss5 & SS5_FEATURE_CONNECT)) {
1886                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
1887                 message_put(message);
1888         } else {
1889                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
1890                 message_put(message);
1891         }
1892
1893         /* start seizing */
1894         ss5_trace_header(p_m_mISDNport, this, SS5_SEIZING_REQ, p_m_b_channel);
1895         end_trace();
1896         new_ss5_state(SS5_STATE_SEIZING);
1897         new_ss5_signal(SS5_SIGNAL_SEND_ON);
1898         p_m_s_sample_nr = 0;
1899         inband_send_on();
1900
1901         p_type = PORT_TYPE_SS5_OUT;
1902         new_state(PORT_STATE_OUT_SETUP);
1903 }
1904
1905 /* MESSAGE_CONNECT */
1906 void Pss5::message_connect(unsigned int epoint_id, int message_id, union parameter *param)
1907 {
1908         memcpy(&p_connectinfo, &param->connectinfo, sizeof(p_connectinfo));
1909
1910         if (p_state != PORT_STATE_CONNECT) {
1911                 new_state(PORT_STATE_CONNECT);
1912                 p_m_s_answer = 1;
1913                 trigger_work(&p_m_s_queue);
1914         }
1915
1916         set_tone("", NULL);
1917 }
1918
1919 /* MESSAGE_DISCONNECT */
1920 void Pss5::message_disconnect(unsigned int epoint_id, int message_id, union parameter *param)
1921 {
1922         /* disconnect and clear forward (release guard) */
1923 //      if ((p_type==PORT_TYPE_SS5_IN && !p_m_mISDNport->tones) /* incomming exchange with no tones */
1924 if (0    || p_type==PORT_TYPE_SS5_OUT) { /* outgoing exchange */
1925                 do_release(param->disconnectinfo.cause, param->disconnectinfo.location);
1926                 return;
1927         }
1928
1929         ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_BACK_REQ, p_m_b_channel);
1930         end_trace();
1931         start_signal(SS5_STATE_CLEAR_BACK);
1932
1933         new_state(PORT_STATE_OUT_DISCONNECT);
1934 }
1935
1936 /* MESSAGE_RELEASE */
1937 void Pss5::message_release(unsigned int epoint_id, int message_id, union parameter *param)
1938 {
1939         do_release(param->disconnectinfo.cause, param->disconnectinfo.location);
1940 }
1941
1942 void Pss5::register_timeout(void)
1943 {
1944         do_release(CAUSE_UNSPECIFIED, LOCATION_PRIVATE_LOCAL);
1945 }
1946
1947 /*
1948  * endpoint sends messages to the port
1949  */
1950 int Pss5::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1951 {
1952         if (PmISDN::message_epoint(epoint_id, message_id, param))
1953                 return(1);
1954
1955         switch(message_id) {
1956                 case MESSAGE_SETUP: /* dial-out command received from epoint */
1957                 if (p_state!=PORT_STATE_IDLE) {
1958                         PERROR("Pss5(%s) ignoring setup because isdn port is not in idle state (or connected for sending display info).\n", p_name);
1959                         break;
1960                 }
1961                 if (p_epointlist && p_state==PORT_STATE_IDLE)
1962                         FATAL("Pss5(%s): epoint pointer is set in idle state, how bad!!\n", p_name);
1963                 message_setup(epoint_id, message_id, param);
1964                 break;
1965
1966                 case MESSAGE_CONNECT: /* call of endpoint is connected */
1967                 message_connect(epoint_id, message_id, param);
1968                 break;
1969
1970                 case MESSAGE_DISCONNECT: /* call has been disconnected */
1971                 message_disconnect(epoint_id, message_id, param);
1972                 break;
1973
1974                 case MESSAGE_RELEASE: /* release isdn port */
1975                 message_release(epoint_id, message_id, param);
1976                 break;
1977
1978                 default:
1979                 PDEBUG(DEBUG_SS5, "Pss5(%s) ss5 port with (caller id %s) received an unhandled message: %d\n", p_name, p_callerinfo.id, message_id);
1980         }
1981
1982         return(1);
1983 }
1984