Experimental crypto feature: Support for libvootp
[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_OUT_DISCONNECT: a clear-back is sent, after DISCONNECT was received
28  * - PORT_STATE_CONNECT: a call is answered on either side.
29  * - PORT_STATE_IN_SETUP: the seizing is received, we wait for the first digit.
30  * - PORT_STATE_IN_OVERLAP: the digits are received.
31  * - PORT_STATE_IN_PROCEEDING: the number is complete, a SETUP is indicated.
32  * - PORT_STATE_IN_DISCONNECT: a clear-back was received, an DISCONNECT is indicated.
33  * - PORT_STATE_RELEASE: the clear forward procedure is started.
34  *
35  */
36
37 #include "main.h"
38
39 //#define DEBUG_DETECT
40
41 /* ss5 signal states */
42 enum {
43         SS5_STATE_IDLE,                 /* no signal */
44         SS5_STATE_SEIZING,              /* seizing */
45         SS5_STATE_PROCEED_TO_SEND,      /* proceed-to-send */
46         SS5_STATE_BUSY_FLASH,           /* busy-flash / clear back */
47         SS5_STATE_ACK_BUSY_FLASH,       /* acknowledge of busy/answer/clear-back */
48         SS5_STATE_ANSWER,               /* answer */
49         SS5_STATE_ACK_ANSWER,           /* acknowledge of busy/answer/clear-back */
50         SS5_STATE_FORWARD_TRANSFER,     /* forward transfer */
51         SS5_STATE_CLEAR_BACK,           /* clear-back */
52         SS5_STATE_ACK_CLEAR_BACK,       /* acknowledge of busy/answer/clear-back */
53         SS5_STATE_CLEAR_FORWARD,        /* clear-forward */
54         SS5_STATE_RELEASE_GUARD,        /* release-guard */
55         SS5_STATE_DIAL_OUT,             /* dialing state (transmitter) */
56         SS5_STATE_DIAL_IN,              /* dialing state (receiver) */
57         SS5_STATE_DIAL_IN_PULSE,        /* dialing state (receiver with pulses) */
58         SS5_STATE_DELAY,                /* after signal wait until next signal can be sent */
59         SS5_STATE_DOUBLE_SEIZE,         /* in case of a double seize, we make the remote size recognize it */
60 };
61 const char *ss5_state_name[] = {
62         "STATE_IDLE",
63         "STATE_SEIZING",
64         "STATE_PROCEED_TO_SEND",
65         "STATE_BUSY_FLASH",
66         "STATE_ACK_BUSY_FLASH",
67         "STATE_ANSWER",
68         "STATE_ACK_ANSWER",
69         "STATE_FORWARD_TRANSFER",
70         "STATE_CLEAR_BACK",
71         "STATE_ACK_CLEAR_BACK",
72         "STATE_CLEAR_FORWARD",
73         "STATE_RELEASE_GUARD",
74         "STATE_DIAL_OUT",
75         "STATE_DIAL_IN",
76         "STATE_DIAL_IN_PULSE",
77         "STATE_DELAY",
78         "STATE_DOUBLE_SEIZE",
79 };
80
81 enum {
82         SS5_SIGNAL_NULL,
83         /* sending signal states */
84         SS5_SIGNAL_SEND_ON,             /* sending signal, waiting for acknowledge */
85         SS5_SIGNAL_SEND_ON_RECOG,       /* sending signal, receiving ack, waiting for recogition timer */
86         SS5_SIGNAL_SEND_OFF,            /* silence, receiving ack, waiting for stop */
87         /* receiving signal states */
88         SS5_SIGNAL_RECEIVE_RECOG,       /* receiving signal, waiting for recognition timer */
89         SS5_SIGNAL_RECEIVE,             /* receiving signal / send ack, waiting for stop */
90         SS5_SIGNAL_DELAY,               /* delay after release guard to prevent ping-pong */
91         /* sending / receiving digit states */
92         SS5_SIGNAL_DIGIT_PAUSE,         /* pausing before sending (next) digit */
93         SS5_SIGNAL_DIGIT_ON,            /* sending digit */
94         SS5_SIGNAL_PULSE_OFF,           /* make */
95         SS5_SIGNAL_PULSE_ON,            /* break */
96 };
97 const char *ss5_signal_name[] = {
98         "NULL",
99         "SIGNAL_SEND_ON",
100         "SIGNAL_SEND_ON_RECOG",
101         "SIGNAL_SEND_OFF",
102         "SIGNAL_RECEIVE_RECOG",
103         "SIGNAL_RECEIVE",
104         "SIGNAL_DELAY",
105         "SIGNAL_DIGIT_PAUSE",
106         "SIGNAL_DIGIT_ON",
107         "SIGNAL_PULSE_OFF",
108         "SIGNAL_PULSE_ON",
109 };
110
111 /* ss5 signal timers (in samples) */
112 #define SS5_TIMER_AFTER_SIGNAL  (100*8) /* wait after signal is terminated */
113 #define SS5_TIMER_KP            (100*8) /* duration of KP1 or KP2 digit */
114 #define SS5_TIMER_DIGIT         (55*8)  /* duration of all other digits */
115 #define SS5_TIMER_PAUSE         (55*8)  /* pause between digits */
116 #define SS5_TIMER_FORWARD       (850*8) /* forward transfer length */
117 #define SS5_TIMER_RECOG_SEIZE   (40*8)  /* recognition time of seizing / proceed-to-send signal */
118 #define SS5_TIMER_RECOG_OTHER   (125*8) /* recognition time of all other f1/f2 signals */
119 #define SS5_TIMER_SIGNAL_LOSS   (15*8)  /* minimum time of signal loss for a continous signal */
120 #define SS5_TIMER_DOUBLE_SEIZE  (850*8) /* double seize length */
121 #define SS5_TIMER_RELEASE_GUARD (850*8) /* be sure to release after clear-forward */
122 #define SS5_TIMER_RELEASE_MAX   (2000*8)/* maximum time for release guard to prevent 'double-releasing' */
123 #define SS5_TIMER_RELEASE_DELAY (4000*8)/* wait after release guard to prevent ping-pong */
124 #define BELL_TIMER_BREAK        (50*8)  /* loop open, tone */
125 #define BELL_TIMER_MAKE         (50*8)  /* loop closed, no tone */
126 #define BELL_TIMER_PAUSE        (800*8) /* interdigit delay */
127 #define BELL_TIMER_RECOG_HANGUP (200*8) /* time to recognize hangup */
128 #define BELL_TIMER_RECOG_END    (300*8) /* recognize end of digit */
129
130 /* ss5 timers */
131 #define SS5_TIMER_OVERLAP       10      /* timeout for overlap digits received on incomming exchange */
132 #define SS5_TIMER_RELEASE       20      /* timeout after disconnect on incomming exchange */
133
134
135 /*
136  * ss5 trace header
137  */
138 enum { /* even values are indications, odd values are requests */
139         SS5_SEIZING_IND,
140         SS5_SEIZING_REQ,
141         SS5_PROCEED_TO_SEND_IND,
142         SS5_PROCEED_TO_SEND_REQ,
143         SS5_BUSY_FLASH_IND,
144         SS5_BUSY_FLASH_REQ,
145         SS5_ANSWER_IND,
146         SS5_ANSWER_REQ,
147         SS5_CLEAR_BACK_IND,
148         SS5_CLEAR_BACK_REQ,
149         SS5_CLEAR_FORWARD_IND,
150         SS5_CLEAR_FORWARD_REQ,
151         SS5_RELEASE_GUARD_IND,
152         SS5_RELEASE_GUARD_REQ,
153         SS5_ACKNOWLEDGE_IND,
154         SS5_ACKNOWLEDGE_REQ,
155         SS5_DOUBLE_SEIZURE_IND,
156         SS5_DOUBLE_SEIZURE_REQ,
157         SS5_DIALING_IND,
158         SS5_DIALING_REQ,
159         SS5_FORWARD_TRANSFER_IND,
160         SS5_FORWARD_TRANSFER_REQ,
161         SS5_TIMEOUT_IND,
162         SS5_QUALITY_IND,
163 };
164 static struct isdn_message {
165         const char *name;
166         unsigned int value;
167 } ss5_message[] = {
168         {"SEIZING RECEIVED", SS5_SEIZING_IND},
169         {"SEIZING SENDING", SS5_SEIZING_REQ},
170         {"PROCEED-TO-SEND RECEIVED", SS5_PROCEED_TO_SEND_IND},
171         {"PROCEED-TO-SEND SENDING", SS5_PROCEED_TO_SEND_REQ},
172         {"BUSY-FLASH RECEIVED", SS5_BUSY_FLASH_IND},
173         {"BUSY-FLASH SENDING", SS5_BUSY_FLASH_REQ},
174         {"ANSWER RECEIVED", SS5_ANSWER_IND},
175         {"ANSWER SENDING", SS5_ANSWER_REQ},
176         {"CLEAR-BACK RECEIVED", SS5_CLEAR_BACK_IND},
177         {"CLEAR-BACK SENDING", SS5_CLEAR_BACK_REQ},
178         {"CLEAR-FORWARD RECEIVED", SS5_CLEAR_FORWARD_IND},
179         {"CLEAR-FORWARD SENDING", SS5_CLEAR_FORWARD_REQ},
180         {"RELEASE-GUARD RECEIVED", SS5_RELEASE_GUARD_IND},
181         {"RELEASE-GUARD SENDING", SS5_RELEASE_GUARD_REQ},
182         {"ACKNOWLEDGE RECEIVED", SS5_ACKNOWLEDGE_IND},
183         {"ACKNOWLEDGE SENDING", SS5_ACKNOWLEDGE_REQ},
184         {"DOUBLE-SEIZURE RECEIVED", SS5_DOUBLE_SEIZURE_IND},
185         {"DOUBLE-SEIZURE SENDING", SS5_DOUBLE_SEIZURE_REQ},
186         {"DIALING RECEIVED", SS5_DIALING_IND},
187         {"DIALING SENDING", SS5_DIALING_REQ},
188         {"FORWARD-TRANSFER RECEIVED", SS5_FORWARD_TRANSFER_IND},
189         {"FORWARD-TRANSFER SENDING", SS5_FORWARD_TRANSFER_REQ},
190         {"TIMEOUT", SS5_TIMEOUT_IND},
191         {"QUALITY REPORT", SS5_QUALITY_IND},
192         {NULL, 0},
193 };
194 static void ss5_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int channel)
195 {
196         int i;
197         char msgtext[64];
198
199         SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
200         /* select message and primitive text */
201         i = 0;
202         while(ss5_message[i].name) {
203 //              if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
204                 if (ss5_message[i].value == msg) {
205                         SCPY(msgtext, ss5_message[i].name);
206                         break;
207                 }
208                 i++;
209         }
210
211         /* init trace with given values */
212         start_trace(mISDNport?mISDNport->portnum:-1,
213                     mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
214                     port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
215                     port?port->p_dialinginfo.id:NULL,
216                     (msg&1)?DIRECTION_OUT:DIRECTION_IN,
217                     CATEGORY_CH,
218                     port?port->p_serial:0,
219                     msgtext);
220         add_trace("channel", NULL, "%d", channel);
221         switch (port->p_type) {
222                 case PORT_TYPE_SS5_OUT:
223                 add_trace("state", NULL, "outgoing");
224                 break;
225                 case PORT_TYPE_SS5_IN:
226                 add_trace("state", NULL, "incomming");
227                 break;
228                 default:
229                 add_trace("state", NULL, "idle");
230                 break;
231         }
232 }
233
234
235 /*
236  * changes release tone into silence
237  * this makes the line sound more authentic
238  */
239 void Pss5::set_tone(const char *dir, const char *name)
240 {
241         if (name && !strcmp(name, "cause_10"))
242                 name = NULL;
243
244         PmISDN::set_tone(dir, name);
245 }
246
247 /*
248  * creation of static channels
249  */
250 void ss5_create_channel(struct mISDNport *mISDNport, int i)
251 {
252         class Pss5              *ss5port;
253         char                    portname[32];
254         struct port_settings    port_settings;
255
256         SPRINT(portname, "%s-%d", mISDNport->name, i+1);
257
258         memset(&port_settings, 0, sizeof(port_settings));
259         SCPY(port_settings.tones_dir, options.tones_dir);
260
261         ss5port = new Pss5(PORT_TYPE_SS5_IDLE, mISDNport, portname, &port_settings, mISDNport->ifport->interface, i + (i>=15) + 1, 1, B_MODE_TRANSPARENT);
262         if (!ss5port)
263                 FATAL("No memory for Pss5 class.\n");
264         if (!ss5port->p_m_b_channel)
265                 FATAL("No bchannel on given index.\n");
266
267         /* connect channel */
268         bchannel_event(mISDNport, ss5port->p_m_b_index, B_EVENT_USE);
269
270 }
271
272
273 /*
274  * hunt for a free line
275  * this function returns a port object in idle state.
276  */
277 class Pss5 *ss5_hunt_line(struct mISDNport *mISDNport)
278 {
279         int i;
280         class Port      *port;
281         class Pss5      *ss5port = NULL;
282         struct select_channel *selchannel; 
283
284         PDEBUG(DEBUG_SS5, "Entered name=%s\n", mISDNport->name);
285         selchannel = mISDNport->ifport->out_channel;
286         while(selchannel) {
287                 switch(selchannel->channel) {
288                         case CHANNEL_FREE: /* free channel */
289                         case CHANNEL_ANY: /* any channel */
290                         for (i = 0; i < mISDNport->b_num; i++) {
291                                 port = mISDNport->b_port[i];
292                                 PDEBUG(DEBUG_SS5, "Checking port %p on index\n", port, i);
293                                 if (!port)
294                                         continue;
295                                 if (port->p_type == PORT_TYPE_SS5_IN || port->p_type == PORT_TYPE_SS5_OUT)
296                                         PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because port not idle type.\n",
297                                                 mISDNport->name, i);
298                                 if (port->p_type != PORT_TYPE_SS5_IDLE)
299                                         continue;
300                                 ss5port = (class Pss5 *)port;
301                                 /* is really idle ? */
302                                 if (ss5port->p_state == PORT_STATE_IDLE
303                                  && ss5port->p_m_s_state == SS5_STATE_IDLE)
304                                         return ss5port;
305                                 PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because p_state=%d, ss5_state=%d.\n",
306                                         mISDNport->name, i, ss5port->p_state,ss5port->p_m_s_state);
307                         }
308                         PDEBUG(DEBUG_SS5, "no free interface\n");
309                         return NULL;
310
311                         case CHANNEL_NO:
312                         break;
313
314                         default:
315                         if (selchannel->channel<1 || selchannel->channel==16)
316                                 break;
317                         i = selchannel->channel-1-(selchannel->channel>=17);
318                         if (i >= mISDNport->b_num)
319                                 break;
320                         port = mISDNport->b_port[i];
321                         if (!port)
322                                 break;
323                         if (port->p_type == PORT_TYPE_SS5_IN || port->p_type == PORT_TYPE_SS5_OUT)
324                                 PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because port not idle type.\n",
325                                         mISDNport->name, i);
326                         if (port->p_type != PORT_TYPE_SS5_IDLE)
327                                 break;
328                         ss5port = (class Pss5 *)port;
329                         /* is really idle ? */
330                         if (ss5port->p_state == PORT_STATE_IDLE
331                          && ss5port->p_m_s_state == SS5_STATE_IDLE)
332                                 return ss5port;
333                         PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because p_state=%d, ss5_state=%d.\n",
334                                 mISDNport->name, i, ss5port->p_state,ss5port->p_m_s_state);
335                 }
336                 selchannel = selchannel->next;
337         }
338         PDEBUG(DEBUG_SS5, "no free interface in channel list\n");
339         return NULL;
340 }
341
342 static int timeout(struct lcr_timer *timer, void *instance, int i)
343 {
344         class Pss5 *ss5 = (class Pss5 *)instance;
345
346         ss5->register_timeout();
347
348         return 0;
349 }
350
351 int queue_event(struct lcr_work *work, void *instance, int index)
352 {
353         class Pss5 *ss5port = (class Pss5 *)instance;
354
355         ss5port->process_queue();
356
357         return 0;
358 }
359
360 /*
361  * constructor
362  */
363 Pss5::Pss5(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, struct interface *interface, int channel, int exclusive, int mode) : PmISDN(type, mISDNport, portname, settings, interface, channel, exclusive, mode)
364 {
365         p_callerinfo.itype = (mISDNport->ifport->interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN;
366         p_m_s_state = SS5_STATE_IDLE;
367         p_m_s_signal = SS5_SIGNAL_NULL;
368         p_m_s_dial[0] = '\0';
369         p_m_s_digit_i = 0;
370         p_m_s_pulsecount = 0;
371         p_m_s_last_digit = ' ';
372         p_m_s_last_digit_used = ' ';
373         p_m_s_signal_loss = 0;
374         p_m_s_decoder_count = 0;
375         //p_m_s_decoder_buffer;
376         p_m_s_sample_nr = 0;
377         p_m_s_quality_value = 0;
378         p_m_s_quality_count = 0;
379         p_m_s_recog = 0;
380         memset(&p_m_s_queue, 0, sizeof(p_m_s_queue));
381         add_work(&p_m_s_queue, queue_event, this, 0);
382         p_m_s_queued_signal = 0;
383         memset(p_m_s_delay_digits, ' ', sizeof(p_m_s_delay_digits));
384         memset(p_m_s_delay_mute, ' ', sizeof(p_m_s_delay_mute));
385         memset(&p_m_s_timer, 0, sizeof(p_m_s_timer));
386         add_timer(&p_m_s_timer, timeout, this, 0);
387
388         /* turn on signalling receiver */
389         inband_receive_on();
390
391         PDEBUG(DEBUG_SS5, "Created new mISDNPort(%s). Currently %d objects use.\n", portname, mISDNport->use);
392 }
393
394
395 /*
396  * destructor
397  */
398 Pss5::~Pss5()
399 {
400         del_timer(&p_m_s_timer);
401         del_work(&p_m_s_queue);
402 }
403
404
405 /*
406  * timeout trigger
407  */
408 void Pss5::register_timeout(void)
409 {
410         ss5_trace_header(p_m_mISDNport, this, SS5_TIMEOUT_IND, p_m_b_channel);
411         end_trace();
412         switch(p_state) {
413         case PORT_STATE_IN_SETUP:
414                 PDEBUG(DEBUG_SS5, "%s: timeout after seize\n", p_name);
415                 do_release(CAUSE_UNSPECIFIED, LOCATION_PRIVATE_LOCAL, SS5_CLEAR_BACK_REQ);
416                 break;
417         case PORT_STATE_IN_OVERLAP:
418                 PDEBUG(DEBUG_SS5, "%s: timeout during dialing\n", p_name);
419                 do_release(CAUSE_UNSPECIFIED, LOCATION_PRIVATE_LOCAL, SS5_CLEAR_BACK_REQ);
420                 break;
421         case PORT_STATE_OUT_DISCONNECT:
422                 PDEBUG(DEBUG_SS5, "%s: timeout after sending busy flash / clear forward\n", p_name);
423                 /* always send clear forward, because release guard only works as a reply to clear forward */
424                 do_release(CAUSE_UNSPECIFIED, LOCATION_PRIVATE_LOCAL, SS5_CLEAR_FORWARD_REQ);
425                 break;
426         }
427 }
428
429 /*
430  * change port state
431  */
432 void Pss5::new_state(int state)
433 {
434         switch(state) {
435         case PORT_STATE_IN_SETUP:
436         case PORT_STATE_IN_OVERLAP:
437                 if (SS5_TIMER_OVERLAP == 0)
438                         break;
439                 PDEBUG(DEBUG_SS5, "%s: starting timeout timer with %d seconds\n", p_name, SS5_TIMER_OVERLAP);
440                 schedule_timer(&p_m_s_timer, SS5_TIMER_OVERLAP, 0);
441                 break;
442         case PORT_STATE_OUT_DISCONNECT:
443                 if (p_type != PORT_TYPE_SS5_IN)
444                         break;
445                 if (SS5_TIMER_RELEASE == 0)
446                         break;
447                 PDEBUG(DEBUG_SS5, "%s: starting timeout timer with %d seconds\n", p_name, SS5_TIMER_RELEASE);
448                 schedule_timer(&p_m_s_timer, SS5_TIMER_RELEASE, 0);
449                 break;
450         default:
451                 PDEBUG(DEBUG_SS5, "%s: stopping timeout timer\n", p_name);
452                 unsched_timer(&p_m_s_timer);
453         }
454         Port::new_state(state);
455 }
456
457 /*
458  * change ss5 states
459  */
460 void Pss5::_new_ss5_state(int state, const char *func, int line)
461 {
462         PDEBUG(DEBUG_SS5, "%s(%s:%d): changing SS5 state from %s to %s\n", p_name, func, line, ss5_state_name[p_m_s_state], ss5_state_name[state]);
463         p_m_s_state = state;
464         p_m_s_signal = SS5_SIGNAL_NULL;
465
466         if (p_m_s_state == SS5_STATE_IDLE && p_m_s_queued_signal)
467                 trigger_work(&p_m_s_queue);
468 }
469
470 void Pss5::process_queue(void)
471 {
472         /* when clear forward is scheduled, we abort current state */
473         if (p_m_s_queued_signal == SS5_CLEAR_FORWARD_REQ)
474                 new_ss5_state(SS5_STATE_IDLE);
475         
476         /* if there is an ongoing signal, we wait until done */
477         if (p_m_s_state != SS5_STATE_IDLE)
478                 return;
479
480         /* this shoud not happen */
481         if (!p_m_s_queued_signal)
482                 return;
483
484         /* start signal */
485         ss5_trace_header(p_m_mISDNport, this, p_m_s_queued_signal, p_m_b_channel);
486         end_trace();
487         switch(p_m_s_queued_signal) {
488         case SS5_ANSWER_REQ:
489                 /* start answer */
490                 p_m_s_queued_signal = 0; /* prevent trigger loop */
491                 start_signal(SS5_STATE_ANSWER);
492                 break;
493         case SS5_BUSY_FLASH_REQ:
494                 /* busy flash */
495                 p_m_s_queued_signal = 0; /* prevent trigger loop */
496                 start_signal(SS5_STATE_BUSY_FLASH);
497                 break;
498         case SS5_CLEAR_BACK_REQ:
499                 /* clear back */
500                 p_m_s_queued_signal = 0; /* prevent trigger loop */
501                 start_signal(SS5_STATE_CLEAR_BACK);
502                 break;
503         case SS5_CLEAR_FORWARD_REQ:
504                 /* clear forward */
505                 p_m_s_queued_signal = 0; /* prevent trigger loop */
506                 start_signal(SS5_STATE_CLEAR_FORWARD);
507                 break;
508         default:
509                 PERROR("unhandled event %d\n", p_m_s_queued_signal);
510                 p_m_s_queued_signal = 0;
511         }
512 }
513
514 void Pss5::_new_ss5_signal(int signal, const char *func, int line)
515 {
516         if (p_m_s_signal)
517                 PDEBUG(DEBUG_SS5, "%s: changing SS5 signal state from %s to %s\n", p_name, ss5_signal_name[p_m_s_signal], ss5_signal_name[signal]);
518         else
519                 PDEBUG(DEBUG_SS5, "%s: changing SS5 signal state to %s\n", p_name, ss5_signal_name[signal]);
520         p_m_s_signal = signal;
521 }
522
523
524 /*
525  * signalling receiver
526  *
527  * this function will be called for every audio received.
528  */
529 void Pss5::inband_receive(unsigned char *buffer, int len)
530 {
531         int count = 0, tocopy, space;
532         char digit;
533         double quality;
534         int mute = 0;
535
536         again:
537         /* how much to copy ? */
538         tocopy = len - count;
539         space = SS5_DECODER_NPOINTS - p_m_s_decoder_count;
540         if (space < 0)
541                 FATAL("p_m_s_decoder_count overflows\n");
542         if (space < tocopy)
543                 tocopy = space;
544         /* copy an count */
545         memcpy(p_m_s_decoder_buffer+p_m_s_decoder_count, buffer+count, tocopy);
546         p_m_s_decoder_count += tocopy;
547         count += tocopy;
548         /* decoder buffer not completely filled ? */
549         if (tocopy < space)
550                 return;
551
552         /* decode one frame */
553         digit = ss5_decode(p_m_s_decoder_buffer, SS5_DECODER_NPOINTS, &quality);
554         p_m_s_decoder_count = 0;
555
556         /* indicate quality of received digit */
557         if ((p_m_mISDNport->ss5 & SS5_FEATURE_QUALITY)) {
558                 if (digit != ' ') {
559                         p_m_s_quality_value += quality;
560                         p_m_s_quality_count++;
561                 } else if (p_m_s_quality_count) {
562                         ss5_trace_header(p_m_mISDNport, this, SS5_QUALITY_IND, p_m_b_channel);
563                         add_trace("digit", NULL, "%c", p_m_s_last_digit);
564                         quality = p_m_s_quality_value/p_m_s_quality_count;
565                         add_trace("quality", NULL, "%3d%%", (int)(quality*100.0));
566                         end_trace();
567                         p_m_s_quality_value = 0;
568                         p_m_s_quality_count = 0;
569                 }
570         }
571
572 #ifdef DEBUG_DETECT
573         if (p_m_s_last_digit != digit && digit != ' ')
574                 PDEBUG(DEBUG_SS5, "%s: detecting signal '%c' start (state=%s signal=%s)\n", p_name, digit, ss5_state_name[p_m_s_state], ss5_signal_name[p_m_s_signal]);
575 #endif
576
577         /* ignore short loss of signal, or change within one decode window */
578         if (p_m_s_signal_loss) {
579                 if (digit == ' ') {
580                         /* still lost */
581                         if (p_m_s_signal_loss >= SS5_TIMER_SIGNAL_LOSS) {
582 #ifdef DEBUG_DETECT
583                                 PDEBUG(DEBUG_SS5, "%s: signal '%c' lost too long\n", p_name, p_m_s_last_digit);
584 #endif
585                                 /* long enough, we stop loss-timer */
586                                 p_m_s_signal_loss = 0;
587                         } else {
588                                 /* not long enough, so we use last signal */
589                                 p_m_s_signal_loss += SS5_DECODER_NPOINTS;
590                                 digit = p_m_s_last_digit;
591                         }
592                 } else {
593                         /* signal is back, we stop timer and store */
594 #ifdef DEBUG_DETECT
595                         PDEBUG(DEBUG_SS5, "%s: signal '%c' lost, but continues with '%c'\n", p_name, p_m_s_last_digit, digit);
596 #endif
597                         p_m_s_signal_loss = 0;
598                         p_m_s_last_digit = digit;
599                 }
600         } else {
601                 if (p_m_s_last_digit != ' ' && digit == ' ') {
602 #ifdef DEBUG_DETECT
603                         PDEBUG(DEBUG_SS5, "%s: signal '%c' lost\n", p_name, p_m_s_last_digit);
604 #endif
605                         /* restore last digit until signal is really lost */
606                         p_m_s_last_digit = digit;
607                         /* starting to loose signal */
608                         p_m_s_signal_loss = SS5_DECODER_NPOINTS;
609                 } else if (digit != p_m_s_last_digit) {
610                         /* digit changes, but we keep old digit until it is detected twice */
611 #ifdef DEBUG_DETECT
612                         PDEBUG(DEBUG_SS5, "%s: signal '%c' changes to '%c'\n", p_name, p_m_s_last_digit, digit);
613 #endif
614                         p_m_s_last_digit = digit;
615                         digit = p_m_s_last_digit_used;
616                 } else {
617                         /* storing last signal, in case it is lost */
618                         p_m_s_last_digit = digit;
619                 }
620         }
621         p_m_s_last_digit_used = digit;
622
623         /* delay decoded tones */
624         if ((p_m_mISDNport->ss5 & SS5_FEATURE_DELAY)) {
625                 /* shift buffer */
626                 memcpy(p_m_s_delay_digits, p_m_s_delay_digits+1, sizeof(p_m_s_delay_digits)-1);
627                 /* first in */
628                 p_m_s_delay_digits[sizeof(p_m_s_delay_digits)-1] = digit;
629                 /* first out */
630                 digit = p_m_s_delay_digits[0];
631         }
632
633         /* clear forward is always recognized */
634         if (digit == 'C' && p_m_s_state != SS5_STATE_CLEAR_FORWARD && p_m_s_state != SS5_STATE_RELEASE_GUARD) {
635                 switch (p_type) {
636                         case PORT_TYPE_SS5_OUT:
637                         PDEBUG(DEBUG_SS5, "%s: received release-guard, waiting for recognition\n", p_name);
638                         break;
639                         case PORT_TYPE_SS5_IN:
640                         PDEBUG(DEBUG_SS5, "%s: received clear-forward, waiting for recognition\n", p_name);
641                         break;
642                         default:
643                         PDEBUG(DEBUG_SS5, "%s: received clear-forward in idle state, waiting for recognition\n", p_name);
644                         break;
645                 }
646                 new_ss5_state(SS5_STATE_RELEASE_GUARD);
647                 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
648                 p_m_s_recog = 0;
649         } else
650         switch(p_m_s_state) {
651                 case SS5_STATE_IDLE:
652                 /* seizing only recognized in port idle state */
653                 if (p_state == PORT_STATE_IDLE) {
654                         if (digit != 'A')
655                                 break;
656                         seize:
657                         PDEBUG(DEBUG_SS5, "%s: received seize, waiting for recognition\n", p_name);
658                         p_type = PORT_TYPE_SS5_IN;
659                         new_ss5_state(SS5_STATE_PROCEED_TO_SEND);
660                         new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
661                         p_m_s_recog = 0;
662                         break;
663                 }
664                 /* other signals */
665                 if (digit == 'A') {
666                         if (p_type != PORT_TYPE_SS5_OUT)
667                                 break;
668                         PDEBUG(DEBUG_SS5, "%s: received answer, waiting for recognition\n", p_name);
669                         new_ss5_state(SS5_STATE_ACK_ANSWER);
670                         new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
671                         p_m_s_recog = 0;
672                         break;
673                 }
674                 if (digit == 'B') {
675                         if (p_type == PORT_TYPE_SS5_IN) {
676                                 if ((p_m_mISDNport->ss5 & SS5_FEATURE_BELL)) {
677                                         new_ss5_state(SS5_STATE_DIAL_IN_PULSE); /* go pulsing state */
678                                         new_ss5_signal(SS5_SIGNAL_PULSE_OFF); /* we are starting with pulse off */
679                                         p_m_s_pulsecount = 0; /* init pulse counter */
680                                         p_m_s_dial[0] = '\0'; /* init dial string */
681                                         pulse_ind(1); /* also inits recogition timer... */
682                                         break;
683                                 }
684                                 PDEBUG(DEBUG_SS5, "%s: received forward-transfer, waiting for recognition\n", p_name);
685                                 /* forward transfer on incomming lines */
686                                 new_ss5_state(SS5_STATE_FORWARD_TRANSFER);
687                                 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
688                                 p_m_s_recog = 0;
689                                 break;
690                         }
691                         if (p_state == PORT_STATE_CONNECT) {
692                                 PDEBUG(DEBUG_SS5, "%s: received clear-back, waiting for recognition\n", p_name);
693                                 new_ss5_state(SS5_STATE_ACK_CLEAR_BACK);
694                         } else {
695                                 PDEBUG(DEBUG_SS5, "%s: received busy-flash, waiting for recognition\n", p_name);
696                                 new_ss5_state(SS5_STATE_ACK_BUSY_FLASH);
697                         }
698                         new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
699                         p_m_s_recog = 0;
700                         break;
701                 }
702                 /* dialing only allowed in incomming setup state */
703                 if (p_state == PORT_STATE_IN_SETUP) {
704                         if (!strchr("1234567890*#abc", digit))
705                                 break;
706                         PDEBUG(DEBUG_SS5, "%s: received dialing start with '%c'\n", p_name, digit);
707                         new_ss5_state(SS5_STATE_DIAL_IN);
708                         new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
709                         p_m_s_dial[0] = '\0';
710                         digit_ind(digit);
711                         break;
712                 }
713                 break;
714                 /* sending seizing */
715                 case SS5_STATE_SEIZING:
716                 switch (p_m_s_signal) {
717                         case SS5_SIGNAL_SEND_ON:
718                         if (digit == 'A') { /* double seize */
719                                 PDEBUG(DEBUG_SS5, "%s: received double seizure\n", p_name, digit);
720                                 double_seizure_ind();
721                                 break;
722                         }
723                         if (digit == 'B') {
724                                 PDEBUG(DEBUG_SS5, "%s: received answer to outgoing seize, waiting for recognition\n", p_name);
725                                 /* set recognition timer */
726                                 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
727                                 p_m_s_recog = 0;
728                         }
729                         break;
730                         case SS5_SIGNAL_SEND_ON_RECOG:
731                         if (digit != 'B') { /* seize */
732                                 PDEBUG(DEBUG_SS5, "%s: answer to outgoing seize is gone before recognition\n", p_name);
733                                 new_ss5_signal(SS5_SIGNAL_SEND_ON);
734 //                              p_m_s_sample_nr = 0;
735 //                              inband_send_on();
736                                 break;
737                         }
738                         p_m_s_recog += SS5_DECODER_NPOINTS;
739                         if (p_m_s_recog < SS5_TIMER_RECOG_SEIZE)
740                                 break;
741                         PDEBUG(DEBUG_SS5, "%s: answer to outgoing seize recognized, turning off, waiting for recognition\n", p_name);
742                         new_ss5_signal(SS5_SIGNAL_SEND_OFF);
743                         break;
744                         case SS5_SIGNAL_SEND_OFF:
745                         if (digit == 'B')
746                                 break;
747                         PDEBUG(DEBUG_SS5, "%s: outgoing seizure is complete, proceeding...\n", p_name);
748                         new_ss5_state(SS5_STATE_IDLE);
749                         proceed_to_send_ind();
750                         break;
751                 }
752                 break;
753                 /* answer to seize */
754                 case SS5_STATE_PROCEED_TO_SEND:
755                 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
756                         if (digit != 'A') {
757                                 PDEBUG(DEBUG_SS5, "%s: incomming seize is gone before recognition\n", p_name);
758                                 new_ss5_state(SS5_STATE_IDLE);
759                                 p_type = PORT_TYPE_SS5_IDLE;
760                                 break;
761                         }
762                         p_m_s_recog += SS5_DECODER_NPOINTS;
763                         if (p_m_s_recog < SS5_TIMER_RECOG_SEIZE)
764                                 break;
765                         PDEBUG(DEBUG_SS5, "%s: incomming seize is recognized, responding...\n", p_name);
766                         new_ss5_signal(SS5_SIGNAL_RECEIVE);
767                         p_m_s_sample_nr = 0;
768                         inband_send_on();
769                         break;
770                 }
771                 if (digit != 'A') {
772                         PDEBUG(DEBUG_SS5, "%s: incomming seize is gone after responding\n", p_name);
773                         new_ss5_state(SS5_STATE_IDLE);
774                         seizing_ind();
775                 }
776                 break;
777                 /* sending busy flash / answer / clear-back */
778                 case SS5_STATE_BUSY_FLASH:
779                 case SS5_STATE_ANSWER:
780                 case SS5_STATE_CLEAR_BACK:
781                 switch (p_m_s_signal) {
782                         case SS5_SIGNAL_SEND_ON:
783                         if (digit == 'A') {
784                                 PDEBUG(DEBUG_SS5, "%s: received acknowledge, waiting for recognition\n", p_name);
785                                 /* set recognition timer */
786                                 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
787                                 p_m_s_recog = 0;
788                         }
789                         break;
790                         case SS5_SIGNAL_SEND_ON_RECOG:
791                         if (digit != 'A') {
792                                 PDEBUG(DEBUG_SS5, "%s: acknowledge is gone before recognition\n", p_name);
793                                 new_ss5_signal(SS5_SIGNAL_SEND_ON);
794 //                              p_m_s_sample_nr = 0;
795 //                              inband_send_on();
796                                 break;
797                         }
798                         p_m_s_recog += SS5_DECODER_NPOINTS;
799                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
800                                 break;
801                         PDEBUG(DEBUG_SS5, "%s: acknowledge recognized, turning off, waiting for recognition\n", p_name);
802                         new_ss5_signal(SS5_SIGNAL_SEND_OFF);
803                         break;
804                         case SS5_SIGNAL_SEND_OFF:
805                         if (digit == 'A')
806                                 break;
807                         PDEBUG(DEBUG_SS5, "%s: outgoing signal is complete\n", p_name);
808                         new_ss5_state(SS5_STATE_IDLE);
809                         break;
810                 }
811                 break;
812                 /* answer to busy-flash / clear back */
813                 case SS5_STATE_ACK_BUSY_FLASH:
814                 case SS5_STATE_ACK_CLEAR_BACK:
815                 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
816                         if (digit != 'B') {
817                                 PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is gone before recognition\n", p_name);
818                                 new_ss5_state(SS5_STATE_IDLE);
819                                 break;
820                         }
821                         p_m_s_recog += SS5_DECODER_NPOINTS;
822                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
823                                 break;
824                         PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is recognized, responding...\n", p_name);
825                         new_ss5_signal(SS5_SIGNAL_RECEIVE);
826                         p_m_s_sample_nr = 0;
827                         inband_send_on();
828                         break;
829                 }
830                 if (digit != 'B') {
831                         PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is gone after responding\n", p_name);
832                         new_ss5_state(SS5_STATE_IDLE);
833                         if (p_m_s_state == SS5_STATE_ACK_BUSY_FLASH)
834                                 busy_flash_ind();
835                         else
836                                 clear_back_ind();
837                 }
838                 break;
839                 /* answer to answer */
840                 case SS5_STATE_ACK_ANSWER:
841                 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
842                         if (digit != 'A') {
843                                 PDEBUG(DEBUG_SS5, "%s: incomming answer is gone before recognition\n", p_name);
844                                 new_ss5_state(SS5_STATE_IDLE);
845                                 break;
846                         }
847                         p_m_s_recog += SS5_DECODER_NPOINTS;
848                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
849                                 break;
850                         PDEBUG(DEBUG_SS5, "%s: incomming answer is recognized, responding...\n", p_name);
851                         new_ss5_signal(SS5_SIGNAL_RECEIVE);
852                         p_m_s_sample_nr = 0;
853                         inband_send_on();
854                         break;
855                 }
856                 if (digit != 'A') {
857                         PDEBUG(DEBUG_SS5, "%s: incomming answer is gone after responding\n", p_name);
858                         new_ss5_state(SS5_STATE_IDLE);
859                         answer_ind();
860                 }
861                 break;
862                 /* sending clear-forward */
863                 case SS5_STATE_CLEAR_FORWARD:
864                 switch (p_m_s_signal) {
865                         case SS5_SIGNAL_SEND_ON:
866                         if (digit == 'C') {
867                                 PDEBUG(DEBUG_SS5, "%s: received answer to clear-forward, waiting for recognition\n", p_name);
868                                 /* set recognition timer */
869                                 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
870                                 p_m_s_recog = 0;
871                         }
872                         break;
873                         case SS5_SIGNAL_SEND_ON_RECOG:
874                         if (digit != 'C') {
875                                 PDEBUG(DEBUG_SS5, "%s: answer to clear-forward is gone before recognition\n", p_name);
876                                 new_ss5_signal(SS5_SIGNAL_SEND_ON);
877 //                              p_m_s_sample_nr = 0;
878 //                              inband_send_on();
879                                 break;
880                         }
881                         p_m_s_recog += SS5_DECODER_NPOINTS;
882                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
883                                 break;
884                         PDEBUG(DEBUG_SS5, "%s: answer to clear-forward recognized, turning off, waiting for recognition\n", p_name);
885                         new_ss5_signal(SS5_SIGNAL_SEND_OFF);
886                         break;
887                         case SS5_SIGNAL_SEND_OFF:
888                         if (digit == 'A') {
889                                 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward answer, continue with seize\n", p_name);
890                                 new_state(PORT_STATE_IDLE);
891                                 goto seize;
892                         }
893                         if (digit == 'C')
894                                 break;
895                         PDEBUG(DEBUG_SS5, "%s: answer to clear-forward is complete\n", p_name);
896                         release_guard_ind();
897                         new_ss5_signal(SS5_SIGNAL_DELAY);
898                         p_m_s_recog = 0; /* use recog to delay */
899                         PDEBUG(DEBUG_SS5, "%s: answer to clear-forward on outgoing interface starting delay to prevent ping-pong\n", p_name);
900                         break;
901                         case SS5_SIGNAL_DELAY:
902                         if (digit == 'A') {
903                                 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward answer, continue with seize\n", p_name);
904                                 new_state(PORT_STATE_IDLE);
905                                 goto seize;
906                         }
907                         p_m_s_recog += SS5_DECODER_NPOINTS;
908                         if (p_m_s_recog < SS5_TIMER_RELEASE_DELAY)
909                                 break;
910                         PDEBUG(DEBUG_SS5, "%s: delay time over, going idle\n", p_name);
911                         new_ss5_state(SS5_STATE_IDLE);
912                         new_state(PORT_STATE_IDLE);
913                         p_type = PORT_TYPE_SS5_IDLE;
914                         break;
915                 }
916                 break;
917                 /* answer to release-guard*/
918                 case SS5_STATE_RELEASE_GUARD:
919                 switch (p_m_s_signal) {
920                         case SS5_SIGNAL_RECEIVE_RECOG:
921                         if (digit != 'C') {
922                                 if (p_type == PORT_TYPE_SS5_OUT)
923                                         PDEBUG(DEBUG_SS5, "%s: incomming release-guard is gone before recognition\n", p_name);
924                                 else
925                                         PDEBUG(DEBUG_SS5, "%s: incomming clear forward is gone before recognition\n", p_name);
926                                 new_ss5_state(SS5_STATE_IDLE);
927                                 break;
928                         }
929                         p_m_s_recog += SS5_DECODER_NPOINTS;
930                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
931                                 break;
932                         if (p_type == PORT_TYPE_SS5_OUT)
933                                 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is recognized, responding...\n", p_name);
934                         else
935                                 PDEBUG(DEBUG_SS5, "%s: incomming clear-forward is recognized, responding...\n", p_name);
936                         new_state(PORT_STATE_RELEASE);
937                         new_ss5_signal(SS5_SIGNAL_RECEIVE);
938                         p_m_s_sample_nr = 0;
939                         inband_send_on();
940                         break;
941                         case SS5_SIGNAL_RECEIVE:
942                         if (digit == 'C'
943                          || p_m_s_sample_nr < 256) /* small hack to keep answer for at least some time */
944                          break;
945 #if 0
946                         if (digit == 'A') {
947                                 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward is received\n", p_name);
948                                 new_state(PORT_STATE_IDLE);
949                                 goto seize;
950                         }
951 #endif
952                         /* if clear forward stops right after recognition on the incomming side,
953                          * the release guard signal stops and may be too short to be recognized at the outgoing side.
954                          * to prevent this, a timer can be started to force a release guard that is long
955                          * enough to be recognized on the outgoing side.
956                          * this will prevent braking via blueboxing (other tricks may still be possible).
957                          */
958                         if ((p_m_mISDNport->ss5 & SS5_FEATURE_RELEASEGUARDTIMER)
959                          && p_m_s_sample_nr < SS5_TIMER_RELEASE_GUARD)
960                                 break;
961                         if (p_type == PORT_TYPE_SS5_OUT)
962                                 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is gone after responding\n", p_name);
963                         else
964                                 PDEBUG(DEBUG_SS5, "%s: incomming clear-forward is gone after responding\n", p_name);
965                         if (p_type == PORT_TYPE_SS5_OUT) {
966                                 release_guard_ind();
967                                 new_ss5_signal(SS5_SIGNAL_DELAY);
968                                 p_m_s_recog = 0; /* use recog to delay */
969                                 PDEBUG(DEBUG_SS5, "%s: incomming release-guard on outgoing interface starting delay to prevent ping-pong\n", p_name);
970                         } else {
971                                 clear_forward_ind();
972                                 new_ss5_state(SS5_STATE_IDLE);
973                         }
974                         break;
975                         case SS5_SIGNAL_DELAY:
976                         if (digit == 'A') {
977                                 PDEBUG(DEBUG_SS5, "%s: received seize right after release guard is gone, continue with seize\n", p_name);
978                                 new_state(PORT_STATE_IDLE);
979                                 goto seize;
980                         }
981                         p_m_s_recog += SS5_DECODER_NPOINTS;
982                         if (p_m_s_recog < SS5_TIMER_RELEASE_DELAY)
983                                 break;
984                         PDEBUG(DEBUG_SS5, "%s: delay time over, going idle\n", p_name);
985                         new_ss5_state(SS5_STATE_IDLE);
986                         new_state(PORT_STATE_IDLE);
987                         p_type = PORT_TYPE_SS5_IDLE;
988                         break;
989                 }
990                 break;
991                 /* wait time to recognize forward transfer */
992                 case SS5_STATE_FORWARD_TRANSFER:
993                 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
994                         if (digit != 'B') {
995                                 PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is gone before recognition\n", p_name);
996                                 new_ss5_state(SS5_STATE_IDLE);
997                                 break;
998                         }
999                         p_m_s_recog += SS5_DECODER_NPOINTS;
1000                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
1001                                 break;
1002                         PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is recognized, responding, if BELL feature was selected...\n", p_name);
1003                         new_ss5_signal(SS5_SIGNAL_RECEIVE);
1004 #if 0
1005                         p_m_s_sample_nr = 0;
1006                         inband_send_on();
1007 #endif
1008                         break;
1009                 }
1010                 if (digit != 'B') {
1011                         PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is gone after recognition\n", p_name);
1012                         new_ss5_state(SS5_STATE_IDLE);
1013                         forward_transfer_ind();
1014                         break;
1015                 }
1016                 break;
1017                 /* dialing is received */
1018                 case SS5_STATE_DIAL_IN:
1019                 if (strchr("1234567890*#abc", digit)) {
1020                         if (p_m_s_signal != SS5_SIGNAL_DIGIT_PAUSE)
1021                                 break;
1022                         PDEBUG(DEBUG_SS5, "%s: incomming digit '%c' is recognized\n", p_name, digit);
1023                         new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1024                         digit_ind(digit);
1025                 } else {
1026                         if (p_m_s_signal != SS5_SIGNAL_DIGIT_ON)
1027                                 break;
1028                         PDEBUG(DEBUG_SS5, "%s: incomming digit is gone after recognition\n", p_name);
1029                         new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
1030                 }
1031                 break;
1032                 case SS5_STATE_DIAL_IN_PULSE:
1033                 if (digit == 'B')
1034                         pulse_ind(1);
1035                 else
1036                         pulse_ind(0);
1037                 break;
1038         }
1039
1040         /* update mute on RX */
1041         if ((p_m_mISDNport->ss5 & SS5_FEATURE_MUTE_RX)) {
1042                 int mdigit;
1043                 memcpy(p_m_s_delay_mute, p_m_s_delay_mute+1, sizeof(p_m_s_delay_mute)-1);
1044                 p_m_s_delay_mute[sizeof(p_m_s_delay_mute)-1] = digit;
1045                 mdigit = p_m_s_delay_mute[0];
1046                 if (mdigit == 'A' || mdigit == 'B' || mdigit == 'C')
1047                         mute = 1;
1048         }
1049
1050         /* mute when TX */
1051         if ((p_m_mISDNport->ss5 & SS5_FEATURE_MUTE_TX)) {
1052                 switch(p_m_s_signal) {
1053                 case SS5_SIGNAL_SEND_ON_RECOG:
1054                 case SS5_SIGNAL_RECEIVE_RECOG:
1055                         if (p_m_s_recog > SS5_DELAY_MUTE)
1056                                 mute = 1;
1057                         break;
1058                 case SS5_SIGNAL_SEND_OFF:
1059                 case SS5_SIGNAL_RECEIVE:
1060                         mute = 1;
1061                         break;
1062                 }
1063         }
1064
1065         /* apply mute state */
1066         if (p_m_mute) {
1067                 /* mute is on */
1068                 if (!mute)
1069                         mute_off();
1070         } else {
1071                 /* mute is off */
1072                 if (mute)
1073                         mute_on();
1074         }
1075
1076         /* something more to decode ? */
1077         if (count != len)
1078                 goto again;
1079 }
1080
1081
1082 /*
1083  * signalling sender
1084  *
1085  * this function generates tones and assembles dial string with digits and pause
1086  * the result is sent to mISDN. it uses the ss5_encode() function.
1087  * except for dialing and forward-transfer, tones are continuous and will not change state.
1088  */
1089 int Pss5::inband_send(unsigned char *buffer, int len)
1090 {
1091         int count = 0; /* sample counter */
1092         int duration;
1093         char digit;
1094         int tocode, tosend;
1095
1096         switch(p_m_s_state) {
1097                 /* turn off transmitter in idle state */
1098                 case SS5_STATE_IDLE:
1099                 inband_send_off();
1100                 break;
1101
1102                 case SS5_STATE_SEIZING:
1103                 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1104                  && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1105                         break;
1106                 duration = -1; /* continuous */
1107                 digit = 'A';
1108                 send:
1109                 /* how much samples do we have left */
1110                 if (duration < 0)
1111                         tocode = len;
1112                 else
1113                         tocode = duration - p_m_s_sample_nr;
1114                 if (tocode > 0) {
1115                         if (tocode > len)
1116                                 tocode = len;
1117                         ss5_encode(buffer, tocode, digit, p_m_s_sample_nr);
1118                         /* increase counters */
1119                         p_m_s_sample_nr += tocode;
1120                         count += tocode;
1121                 }
1122                 /* more to come ? */
1123                 if (duration > 0 && p_m_s_sample_nr >= duration) {
1124                         PDEBUG(DEBUG_SS5, "%s: sending tone '%c' complete, starting delay\n", p_name, digit);
1125                         if (p_m_s_state == SS5_STATE_DOUBLE_SEIZE) {
1126                                 do_release(CAUSE_NOCHANNEL, LOCATION_PRIVATE_LOCAL, SS5_CLEAR_FORWARD_REQ);
1127                                 break;
1128                         }
1129                         new_ss5_state(SS5_STATE_DELAY);
1130                         p_m_s_sample_nr = 0;
1131                 }
1132 #if 0
1133                 /* stop sending if too long */
1134                 if (duration < 0 && p_m_s_sample_nr >= SS5_TIMER_MAX_SIGNAL) {
1135                         PDEBUG(DEBUG_SS5, "%s: sending tone '%c' too long, stopping\n", p_name, digit);
1136                         inband_send_off();
1137                         break;
1138                 }
1139 #endif
1140                 break;
1141                 /* incomming seizing */
1142                 case SS5_STATE_PROCEED_TO_SEND:
1143                 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1144                         break;
1145                 duration = -1; /* continuous */
1146                 digit = 'B';
1147                 goto send;
1148
1149                 case SS5_STATE_BUSY_FLASH:
1150                 case SS5_STATE_CLEAR_BACK:
1151                 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1152                  && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1153                         break;
1154                 duration = -1; /* continuous */
1155                 digit = 'B';
1156                 goto send;
1157
1158                 case SS5_STATE_ANSWER:
1159                 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1160                  && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1161                         break;
1162                 duration = -1; /* continuous */
1163                 digit = 'A';
1164                 goto send;
1165
1166                 case SS5_STATE_ACK_BUSY_FLASH:
1167                 case SS5_STATE_ACK_ANSWER:
1168                 case SS5_STATE_ACK_CLEAR_BACK:
1169                 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1170                         break;
1171                 duration = -1; /* continuous */
1172                 digit = 'A';
1173                 goto send;
1174
1175 #if 0
1176                 case SS5_STATE_FORWARD_TRANSFER:
1177                 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1178                         break;
1179                 /* only on bell systems continue and acknowledge tone */
1180                 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_BELL))
1181                         break;
1182                 duration = SS5_TIMER_FORWARD;
1183                 digit = 'B';
1184                 goto send;
1185 #endif
1186
1187                 case SS5_STATE_CLEAR_FORWARD:
1188                 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1189                  && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1190                         break;
1191                 duration = -1; /* continuous */
1192                 digit = 'C';
1193                 goto send;
1194
1195                 case SS5_STATE_RELEASE_GUARD:
1196                 if (p_m_s_signal != SS5_SIGNAL_RECEIVE
1197                  && p_m_s_signal != SS5_SIGNAL_DELAY)
1198                         break;
1199                 /* prevent from sending release guard too long */
1200                 if (p_m_s_sample_nr >= SS5_TIMER_RELEASE_MAX)
1201                         break;
1202                 duration = -1; /* continuous */
1203                 digit = 'C';
1204                 goto send;
1205
1206                 case SS5_STATE_DIAL_OUT:
1207                 if ((p_m_mISDNport->ss5 & SS5_FEATURE_PULSEDIALING))
1208                         count = inband_dial_pulse(buffer, len, count);
1209                 else
1210                         count = inband_dial_mf(buffer, len, count);
1211                 break;
1212                 break;
1213
1214                 case SS5_STATE_DELAY:
1215                 tosend = len - count;
1216                 memset(buffer+count, audio_s16_to_law[0], tosend);
1217                 p_m_s_sample_nr += tosend;
1218                 count += tosend;
1219                 if (p_m_s_sample_nr >= SS5_TIMER_AFTER_SIGNAL) {
1220                         PDEBUG(DEBUG_SS5, "%s: delay done, ready for next signal\n", p_name);
1221                         new_ss5_state(SS5_STATE_IDLE);
1222                         inband_send_off();
1223                 }
1224                 break;
1225
1226                 case SS5_STATE_DOUBLE_SEIZE:
1227                 duration = SS5_TIMER_DOUBLE_SEIZE;
1228                 digit = 'A';
1229                 goto send;
1230
1231                 /* nothing to send */
1232                 default:
1233                 PERROR("inband signalling is turned on, but no signal is processed here.");
1234                 new_ss5_state(SS5_STATE_IDLE);
1235                 inband_send_off();
1236                 return 0;
1237         }
1238
1239         /* return (partly) filled buffer */
1240         return count;
1241 }
1242
1243
1244 int Pss5::inband_dial_mf(unsigned char *buffer, int len, int count)
1245 {
1246         int duration;
1247         int tocode, tosend;
1248         char digit;
1249
1250         /* dialing
1251          *
1252          * p_m_s_dial: digits to be dialed
1253          * p_m_s_digit_i: current digit counter
1254          * p_m_s_signal: current signal state
1255          * p_m_s_sample_nr: current sample number
1256          */
1257         again:
1258         /* get digit and duration */
1259         digit = p_m_s_dial[p_m_s_digit_i];
1260         if (!digit) { /* if end of string reached */
1261                 new_ss5_state(SS5_STATE_DELAY);
1262                 p_m_s_sample_nr = 0;
1263                 return count;
1264         }
1265         if (p_m_s_signal == SS5_SIGNAL_DIGIT_ON) {
1266                 if (!p_m_s_digit_i) // first digit
1267                         duration = SS5_TIMER_KP;
1268                 else
1269                         duration = SS5_TIMER_DIGIT;
1270         } else {
1271                 duration = SS5_TIMER_PAUSE;
1272         }
1273         /* end of digit/pause ? */
1274         if (p_m_s_sample_nr >= duration) {
1275                 p_m_s_sample_nr = 0;
1276                 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE)
1277                         new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1278                 else {
1279                         new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
1280                         p_m_s_digit_i++;
1281                         goto again;
1282                 }
1283         }
1284         /* how much samples do we have left */
1285         tosend = len - count;
1286         tocode = duration - p_m_s_sample_nr;
1287         if (tocode < 0)
1288                 FATAL("sample_nr overrun duration");
1289         if (tosend < tocode)
1290                 tocode = tosend;
1291         /* digit or pause */
1292         if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE) {
1293                 memset(buffer+count, audio_s16_to_law[0], tocode);
1294 //              printf("coding pause %d bytes\n", tocode);
1295         } else {
1296                 ss5_encode(buffer+count, tocode, digit, p_m_s_sample_nr);
1297 //              printf("coding digit '%c' %d bytes\n", digit, tocode);
1298         }
1299         /* increase counters */
1300         p_m_s_sample_nr += tocode;
1301         count += tocode;
1302         /* can we take more ? */
1303         if (len != count)
1304                 goto again;
1305         return count;
1306 }
1307
1308
1309 int Pss5::inband_dial_pulse(unsigned char *buffer, int len, int count)
1310 {
1311         int tocode, tosend;
1312         int duration;
1313         char digit;
1314
1315         /* dialing
1316          *
1317          * p_m_s_dial: digits to be dialed
1318          * p_m_s_digit_i: current digit counter
1319          * p_m_s_signal: current signal state
1320          * p_m_s_sample_nr: current sample number
1321          */
1322         again:
1323         /* get digit */
1324         digit = p_m_s_dial[p_m_s_digit_i];
1325         if (!digit) { /* if end of string reached */
1326                 new_ss5_state(SS5_STATE_DELAY);
1327                 p_m_s_sample_nr = 0;
1328                 return count;
1329         }
1330         /* convert digit to pulse */
1331         switch (digit) {
1332                 case '1':
1333                 case '2':
1334                 case '3':
1335                 case '4':
1336                 case '5':
1337                 case '6':
1338                 case '7':
1339                 case '8':
1340                 case '9':
1341                 digit -= '0';
1342                 break;
1343                 case '0':
1344                 digit = 10;
1345                 break;
1346                 case '*':
1347                 digit = 11;
1348                 break;
1349                 case '#':
1350                 digit = 12;
1351                 break;
1352                 default:
1353                 p_m_s_digit_i++;
1354                 goto again;
1355         }
1356         /* get duration */
1357         if (p_m_s_signal == SS5_SIGNAL_DIGIT_ON) {
1358                 if (p_m_s_pulsecount & 1)
1359                         duration = BELL_TIMER_MAKE; /* loop closed */
1360                 else
1361                         duration = BELL_TIMER_BREAK; /* loop open, tone */
1362         } else {
1363                 duration = BELL_TIMER_PAUSE;
1364         }
1365         /* end of digit/pause ? */
1366         if (p_m_s_sample_nr >= duration) {
1367                 p_m_s_sample_nr = 0;
1368                 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE) {
1369                         new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1370                         PDEBUG(DEBUG_SS5, "%s: starting pusling digit '%c'\n", p_name, digit);
1371                 } else {
1372                         p_m_s_pulsecount++; /* toggle pulse */
1373                         if (!(p_m_s_pulsecount & 1)) {
1374                                 /* pulse now on again, but if end is reached... */
1375                                 if (p_m_s_pulsecount == (digit<<1)) {
1376                                         new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
1377                                         p_m_s_pulsecount = 0;
1378                                         p_m_s_digit_i++;
1379                                         goto again;
1380                                 }
1381                         }
1382                 }
1383         }
1384         /* how much samples do we have left */
1385         tosend = len - count;
1386         tocode = duration - p_m_s_sample_nr;
1387         if (tocode < 0)
1388                 FATAL("sample_nr overrun duration");
1389         if (tosend < tocode)
1390                 tocode = tosend;
1391         /* digit or pause */
1392         if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE
1393          || (p_m_s_pulsecount&1)) /* ...or currently on and no pulse */
1394                 memset(buffer+count, audio_s16_to_law[0], tocode);
1395         else
1396                 ss5_encode(buffer+count, tocode, 'B', p_m_s_sample_nr);
1397         /* increase counters */
1398         p_m_s_sample_nr += tocode;
1399         count += tocode;
1400         /* can we take more ? */
1401         if (len != count)
1402                 goto again;
1403         return count;
1404 }
1405
1406
1407 /*
1408  * start signal
1409  */ 
1410 void Pss5::start_signal(int state)
1411 {
1412         PDEBUG(DEBUG_SS5, "%s: starting singal '%s'\n", p_name, ss5_state_name[state]);
1413         /* start signal */
1414         new_ss5_state(state);
1415         if (state == SS5_STATE_DIAL_OUT) {
1416                 p_m_s_digit_i = 0;
1417                 p_m_s_pulsecount = 0;
1418                 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1419         } else
1420                 new_ss5_signal(SS5_SIGNAL_SEND_ON);
1421
1422         /* double seize must continue the current seize tone, so don't reset sample_nr */
1423         if (state != SS5_STATE_DOUBLE_SEIZE) {
1424                 /* (re)set sound phase to 0 */
1425                 p_m_s_sample_nr = 0;
1426         }
1427
1428         /* turn on inband transmitter */
1429         inband_send_on();
1430 }
1431
1432
1433 /*
1434  * handles all indications
1435  */
1436 void Pss5::seizing_ind(void)
1437 {
1438         ss5_trace_header(p_m_mISDNport, this, SS5_SEIZING_IND, p_m_b_channel);
1439         end_trace();
1440
1441         new_state(PORT_STATE_IN_SETUP);
1442         set_tone("", "noise");
1443 }
1444
1445 void Pss5::digit_ind(char digit)
1446 {
1447         int i;
1448         char string[128] = "", dial[128] = "";
1449         int dash, first_digit, last_was_digit;
1450
1451         /* add digit */
1452         SCCAT(p_m_s_dial, digit);
1453
1454         if (p_state == PORT_STATE_IN_SETUP)
1455                 new_state(PORT_STATE_IN_OVERLAP);
1456
1457         /* not last digit ? */
1458         if (digit != 'c')
1459                 return;
1460
1461         /* parse string */
1462         dash = 0; /* dash must be used next time */
1463         first_digit = 1;
1464         last_was_digit = 0;
1465         p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
1466         for (i = 0; p_m_s_dial[i]; i++) {
1467                 if (dash || (last_was_digit && (p_m_s_dial[i]<'0' || p_m_s_dial[i]>'9')))
1468                         SCCAT(string, '-');
1469                 dash = 0;
1470                 last_was_digit = 0;
1471                 switch(p_m_s_dial[i]) {
1472                         case '1':
1473                         case '2':
1474                         case '3':
1475                         case '4':
1476                         case '5':
1477                         case '6':
1478                         case '7':
1479                         case '8':
1480                         case '9':
1481                         case '0':
1482                         if (first_digit)
1483                                 dash = 1;
1484                         first_digit = 0;
1485                         last_was_digit = 1;
1486                         SCCAT(string, p_m_s_dial[i]);
1487                         SCCAT(dial, p_m_s_dial[i]);
1488                         break;
1489                         case '*':
1490                         SCAT(string, "C11");
1491                         SCCAT(dial, p_m_s_dial[i]);
1492                         dash = 1;
1493                         break;
1494                         case '#':
1495                         SCAT(string, "C12");
1496                         SCCAT(dial, p_m_s_dial[i]);
1497                         dash = 1;
1498                         break;
1499                         case 'a':
1500                         SCAT(string, "KP1");
1501                         SCCAT(dial, p_m_s_dial[i]);
1502                         dash = 1;
1503                         break;
1504                         case 'b':
1505                         SCAT(string, "KP2");
1506                         SCCAT(dial, p_m_s_dial[i]);
1507                         dash = 1;
1508                         break;
1509                         case 'c':
1510                         SCAT(string, "ST");
1511                         dash = 1;
1512                         break;
1513                         default:
1514                         break;
1515                 }
1516         }
1517         ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1518         add_trace("string", NULL, "%s", string);
1519         add_trace("number", NULL, "%s", dial);
1520         end_trace();
1521         new_ss5_state(SS5_STATE_IDLE);
1522
1523         do_setup(dial, 1);
1524         new_state(PORT_STATE_IN_PROCEEDING);
1525 }
1526
1527 void Pss5::pulse_ind(int on)
1528 {
1529         struct lcr_msg *message;
1530         char dial[3] = "a.";
1531
1532         if (p_m_s_signal == SS5_SIGNAL_PULSE_OFF) {
1533                 if (on) {
1534                         /* pulse turns on */
1535                         p_m_s_recog = 0;
1536                         new_ss5_signal(SS5_SIGNAL_PULSE_ON);
1537                         /* pulse turns of, count it */
1538                         p_m_s_pulsecount++;
1539                         PDEBUG(DEBUG_SS5, "%s: pulse turns on, counting\n", p_name);
1540                 } else {
1541                         /* pulse remains off */
1542                         p_m_s_recog += SS5_DECODER_NPOINTS;
1543                         /* not recognized end of digit, we wait... */
1544                         if (p_m_s_recog < BELL_TIMER_RECOG_END)
1545                                 return;
1546                         PDEBUG(DEBUG_SS5, "%s: pulse remains off, counted %d pulses\n", p_name, p_m_s_pulsecount);
1547                         if (p_m_s_pulsecount >= 12)
1548                                 dial[1] = '#';
1549                         else if (p_m_s_pulsecount == 11)
1550                                 dial[1] = '*';
1551                         else if (p_m_s_pulsecount == 10)
1552                                 dial[1] = '0';
1553                         else
1554                                 dial[1] = p_m_s_pulsecount + '0';
1555                         ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1556                         add_trace("digit", NULL, "%s", dial+1);
1557                         add_trace("pulses", NULL, "%d", p_m_s_pulsecount);
1558                         end_trace();
1559                         if (p_state == PORT_STATE_IN_SETUP) {
1560                                 /* sending digit as setup */
1561                                 do_setup(dial, 0); /* include 'a' == KP1 */
1562                                 new_state(PORT_STATE_IN_OVERLAP);
1563                         } else {
1564                                 /* sending digit as information */
1565                                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_INFORMATION);
1566                                 SCPY(message->param.information.id, dial+1);
1567                                 message_put(message);
1568                         }
1569                                 new_ss5_state(SS5_STATE_IDLE);
1570                         /* done rx pulses, return to idle */
1571                         new_ss5_state(SS5_STATE_IDLE);
1572                 }
1573         } else {
1574                 if (on) {
1575                         /* pulse remains on */
1576                         p_m_s_recog += SS5_DECODER_NPOINTS;
1577                 } else {
1578                         /* pulse turns off */
1579                         if (p_m_s_recog >= BELL_TIMER_RECOG_HANGUP) {
1580                                 PDEBUG(DEBUG_SS5, "%s: long pulse turns off, releasing\n", p_name);
1581                                 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1582                                 add_trace("longtone", NULL, "releases call");
1583                                 end_trace();
1584                                 /* long pulse is gone, release current connection, if any */
1585                                 while(p_epointlist) {
1586                                         message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1587                                         message->param.disconnectinfo.location = LOCATION_BEYOND;
1588                                         message->param.disconnectinfo.cause = CAUSE_NORMAL;
1589                                         message_put(message);
1590                                         free_epointlist(p_epointlist);
1591                                 }
1592                                 set_tone("", NULL);
1593                                 /* return to setup state */
1594                                 new_state(PORT_STATE_IN_SETUP);
1595                                 new_ss5_state(SS5_STATE_IDLE);
1596                                 return;
1597                         }
1598                         PDEBUG(DEBUG_SS5, "%s: short pulse turns off, releasing\n", p_name);
1599                         p_m_s_recog = 0;
1600                         new_ss5_signal(SS5_SIGNAL_PULSE_OFF);
1601                 }
1602         }
1603 }
1604
1605 void Pss5::proceed_to_send_ind(void)
1606 {
1607         ss5_trace_header(p_m_mISDNport, this, SS5_PROCEED_TO_SEND_IND, p_m_b_channel);
1608         end_trace();
1609
1610         SCPY(p_m_s_dial, p_dialinginfo.id);
1611         start_signal(SS5_STATE_DIAL_OUT);
1612
1613         new_state(PORT_STATE_OUT_OVERLAP);
1614 }
1615
1616 void Pss5::busy_flash_ind(void)
1617 {
1618         struct lcr_msg *message;
1619
1620         ss5_trace_header(p_m_mISDNport, this, SS5_BUSY_FLASH_IND, p_m_b_channel);
1621         end_trace();
1622
1623         /* busy before dialing ? */
1624         if (!p_epointlist)
1625                 return;
1626
1627         if (!(p_m_mISDNport->ss5 & SS5_FEATURE_NODISCONNECT)) {
1628                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DISCONNECT);
1629                 message->param.disconnectinfo.location = LOCATION_BEYOND;
1630                 message->param.disconnectinfo.cause = CAUSE_BUSY;
1631                 message_put(message);
1632         }
1633
1634         new_state(PORT_STATE_IN_DISCONNECT);
1635 }
1636
1637 void Pss5::answer_ind(void)
1638 {
1639         struct lcr_msg *message;
1640
1641         ss5_trace_header(p_m_mISDNport, this, SS5_ANSWER_IND, p_m_b_channel);
1642         end_trace();
1643
1644         /* answer before dialing ? */
1645         if (!p_epointlist)
1646                 return;
1647
1648         /* already connected */
1649         if (!(p_m_mISDNport->ss5 & SS5_FEATURE_CONNECT)) {
1650                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
1651                 message_put(message);
1652         }
1653
1654         new_state(PORT_STATE_CONNECT);
1655 }
1656
1657 void Pss5::forward_transfer_ind(void)
1658 {
1659 //      struct lcr_msg *message;
1660
1661         ss5_trace_header(p_m_mISDNport, this, SS5_FORWARD_TRANSFER_IND, p_m_b_channel);
1662         end_trace();
1663
1664 #if 0
1665         /* if BELL flavor bluebox flag is set, use it to seize a new line */
1666         if (!(p_m_mISDNport->ss5 & SS5_FEATURE_BELL))
1667                 return;
1668
1669         /* special BELL flavor hack to clear a line and seize a new one */
1670         while(p_epointlist) {
1671                 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1672                 message->param.disconnectinfo.location = LOCATION_BEYOND;
1673                 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1674                 message_put(message);
1675                 free_epointlist(p_epointlist);
1676         }
1677         set_tone("", NULL);
1678         new_state(PORT_STATE_IN_SETUP);
1679 #endif
1680 }
1681
1682 void Pss5::clear_back_ind(void)
1683 {
1684         struct lcr_msg *message;
1685
1686         ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_BACK_IND, p_m_b_channel);
1687         end_trace();
1688
1689         /* nobody? */
1690         if (!p_epointlist)
1691                 return;
1692
1693         if (!(p_m_mISDNport->ss5 & SS5_FEATURE_NODISCONNECT)) {
1694                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DISCONNECT);
1695                 message->param.disconnectinfo.location = LOCATION_BEYOND;
1696                 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1697                 message_put(message);
1698         }
1699
1700         new_state(PORT_STATE_IN_DISCONNECT);
1701 }
1702
1703 void Pss5::clear_forward_ind(void)
1704 {
1705         struct lcr_msg *message;
1706
1707         ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_FORWARD_IND, p_m_b_channel);
1708         end_trace();
1709
1710         new_state(PORT_STATE_IDLE);
1711         set_tone("", NULL);
1712         p_type = PORT_TYPE_SS5_IDLE;
1713
1714         /* someone ? */
1715         if (!p_epointlist)
1716                 return;
1717
1718         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1719         message->param.disconnectinfo.location = LOCATION_BEYOND;
1720         message->param.disconnectinfo.cause = CAUSE_NORMAL;
1721         message_put(message);
1722         free_epointlist(p_epointlist);
1723
1724 }
1725
1726 void Pss5::release_guard_ind(void)
1727 {
1728         struct lcr_msg *message;
1729
1730         ss5_trace_header(p_m_mISDNport, this, SS5_RELEASE_GUARD_IND, p_m_b_channel);
1731         end_trace();
1732
1733         set_tone("", NULL);
1734
1735         /* someone ? */
1736         if (!p_epointlist)
1737                 return;
1738
1739         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1740         message->param.disconnectinfo.location = LOCATION_BEYOND;
1741         message->param.disconnectinfo.cause = CAUSE_NORMAL;
1742         message_put(message);
1743         free_epointlist(p_epointlist);
1744 }
1745
1746 void Pss5::double_seizure_ind(void)
1747 {
1748         ss5_trace_header(p_m_mISDNport, this, SS5_DOUBLE_SEIZURE_IND, p_m_b_channel);
1749         end_trace();
1750         ss5_trace_header(p_m_mISDNport, this, SS5_DOUBLE_SEIZURE_REQ, p_m_b_channel);
1751         end_trace();
1752
1753         /* start double seizure sequence, so remote exchange will recognize it */
1754         start_signal(SS5_STATE_DOUBLE_SEIZE);
1755 }
1756
1757
1758 /*
1759  * shuts down by sending a clear forward and releasing endpoint
1760  */
1761 void Pss5::do_release(int cause, int location, int signal)
1762 {
1763         struct lcr_msg *message;
1764
1765         /* sending release to endpoint */
1766         while(p_epointlist) {
1767                 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1768                 message->param.disconnectinfo.location = location;
1769                 message->param.disconnectinfo.cause = cause;
1770                 message_put(message);
1771                 free_epointlist(p_epointlist);
1772         }
1773
1774 //      if (p_state != PORT_STATE_RELEASE) {
1775                 p_m_s_queued_signal = signal;
1776                 if (signal == SS5_CLEAR_FORWARD_REQ) {
1777                         new_state(PORT_STATE_RELEASE);
1778                         set_tone("", "noise");
1779                 } else
1780                         new_state(PORT_STATE_OUT_DISCONNECT);
1781                 trigger_work(&p_m_s_queue);
1782 //      }
1783 }
1784
1785
1786 /*
1787  * create endpoint and send setup
1788  */
1789 void Pss5::do_setup(char *dial, int complete)
1790 {
1791         class Endpoint *epoint;
1792         struct lcr_msg *message;
1793
1794         SCPY(p_dialinginfo.id, dial);
1795         p_dialinginfo.sending_complete = complete;
1796         p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
1797         p_callerinfo.screen = INFO_SCREEN_NETWORK;
1798         p_callerinfo.ntype = INFO_NTYPE_NOTPRESENT;
1799         p_callerinfo.isdn_port = p_m_portnum;
1800         SCPY(p_callerinfo.interface, p_m_mISDNport->ifport->interface->name);
1801
1802         p_capainfo.bearer_capa = INFO_BC_AUDIO;
1803         p_capainfo.bearer_info1 = (options.law=='a')?3:2;
1804         p_capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
1805         p_capainfo.hlc = INFO_HLC_NONE;
1806         p_capainfo.exthlc = INFO_HLC_NONE;
1807         p_capainfo.source_mode = B_MODE_TRANSPARENT;
1808
1809         /* create endpoint */
1810         if (p_epointlist)
1811                 FATAL("Incoming call but already got an endpoint.\n");
1812         if (!(epoint = new Endpoint(p_serial, 0)))
1813                 FATAL("No memory for Endpoint instance\n");
1814         epoint->ep_app = new_endpointapp(epoint, 0, p_m_mISDNport->ifport->interface->app); //incoming
1815         epointlist_new(epoint->ep_serial);
1816
1817         /* send setup message to endpoit */
1818         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
1819         message->param.setup.isdn_port = p_m_portnum;
1820         message->param.setup.port_type = p_type;
1821 //      message->param.setup.dtmf = !p_m_mISDNport->ifport->nodtmf;
1822         memcpy(&message->param.setup.dialinginfo, &p_dialinginfo, sizeof(struct dialing_info));
1823         memcpy(&message->param.setup.callerinfo, &p_callerinfo, sizeof(struct caller_info));
1824         memcpy(&message->param.setup.redirinfo, &p_redirinfo, sizeof(struct redir_info));
1825         memcpy(&message->param.setup.capainfo, &p_capainfo, sizeof(struct capa_info));
1826         message_put(message);
1827
1828 }
1829
1830
1831
1832 /*
1833  * handles all messages from endpoint
1834  */
1835
1836 /* MESSAGE_SETUP */
1837 void Pss5::message_setup(unsigned int epoint_id, int message_id, union parameter *param)
1838 {
1839         struct lcr_msg *message;
1840         int i;
1841         char string[128] = "", dial[128] = "";
1842         int dash, first_digit, last_was_digit;
1843
1844         if (p_epointlist) {
1845                 PERROR("endpoint already exist.\n");
1846                 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1847                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1848                 message->param.disconnectinfo.cause = CAUSE_UNSPECIFIED;
1849                 message_put(message);
1850                 return;
1851         }
1852
1853         /* copy setup infos to port */
1854         memcpy(&p_callerinfo, &param->setup.callerinfo, sizeof(p_callerinfo));
1855         memcpy(&p_dialinginfo, &param->setup.dialinginfo, sizeof(p_dialinginfo));
1856         memcpy(&p_capainfo, &param->setup.capainfo, sizeof(p_capainfo));
1857         memcpy(&p_redirinfo, &param->setup.redirinfo, sizeof(p_redirinfo));
1858         /* screen outgoing caller id */
1859         do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_m_mISDNport->ifport->interface->name);
1860         do_screen(1, p_callerinfo.id2, sizeof(p_callerinfo.id2), &p_callerinfo.ntype2, &p_callerinfo.present2, p_m_mISDNport->ifport->interface->name);
1861
1862         /* parse dial string  */
1863         dash = 0; /* dash must be used next time */
1864         first_digit = 1;
1865         last_was_digit = 0;
1866         for (i = 0; p_dialinginfo.id[i]; i++) {
1867                 if (dash || (last_was_digit && (p_dialinginfo.id[i]<'0' || p_dialinginfo.id[i]>'9')))
1868                         SCCAT(string, '-');
1869                 dash = 0;
1870                 last_was_digit = 0;
1871                 switch(p_dialinginfo.id[i]) {
1872                         case '1':
1873                         case '2':
1874                         case '3':
1875                         case '4':
1876                         case '5':
1877                         case '6':
1878                         case '7':
1879                         case '8':
1880                         case '9':
1881                         case '0':
1882                         if (i && first_digit)
1883                                 dash = 1;
1884                         first_digit = 0;
1885                         last_was_digit = 1;
1886                         SCCAT(string, p_dialinginfo.id[i]);
1887                         SCCAT(dial, p_dialinginfo.id[i]);
1888                         break;
1889                         case '*':
1890                         SCAT(string, "C11");
1891                         SCCAT(dial, '*');
1892                         dash = 1;
1893                         break;
1894                         case '#':
1895                         SCAT(string, "C12");
1896                         SCCAT(dial, '#');
1897                         dash = 1;
1898                         break;
1899                         case 'a':
1900                         SCAT(string, "KP1");
1901                         SCCAT(dial, 'a');
1902                         dash = 1;
1903                         break;
1904                         case 'b':
1905                         SCAT(string, "KP2");
1906                         SCCAT(dial, 'b');
1907                         dash = 1;
1908                         break;
1909                         case 'c':
1910                         SCAT(string, "ST");
1911                         SCCAT(dial, 'c');
1912                         dash = 1;
1913                         case 'K':
1914                         i++;
1915                         if (p_dialinginfo.id[i] != 'P')
1916                                 goto dial_error;
1917                         i++;
1918                         if (p_dialinginfo.id[i] == '1') {
1919                                 SCAT(string, "KP1");
1920                                 SCCAT(dial, 'a');
1921                                 dash = 1;
1922                                 break;
1923                         }
1924                         if (p_dialinginfo.id[i] == '2') {
1925                                 SCAT(string, "KP2");
1926                                 SCCAT(dial, 'b');
1927                                 dash = 1;
1928                                 break;
1929                         }
1930                         goto dial_error;
1931                         case 'C':
1932                         i++;
1933                         if (p_dialinginfo.id[i] != '1')
1934                                 goto dial_error;
1935                         i++;
1936                         if (p_dialinginfo.id[i] == '1') {
1937                                 SCAT(string, "C11");
1938                                 SCCAT(dial, 'a');
1939                                 dash = 1;
1940                                 break;
1941                         }
1942                         if (p_dialinginfo.id[i] == '2') {
1943                                 SCAT(string, "C12");
1944                                 SCCAT(dial, 'b');
1945                                 dash = 1;
1946                                 break;
1947                         }
1948                         goto dial_error;
1949                         case 'S':
1950                         i++;
1951                         if (p_dialinginfo.id[i] != 'T')
1952                                 goto dial_error;
1953                         SCAT(string, "ST");
1954                         SCCAT(dial, 'c');
1955                         dash = 1;
1956                         break;
1957                         default:
1958                         break;
1959                 }
1960                 /* stop, if ST */
1961                 if (dial[0] && dial[strlen(dial)-1] == 'c')
1962                         break;
1963         }
1964         /* terminate */
1965         if (dial[0] && dial[strlen(dial)-1]!='c') {
1966                 SCCAT(string, '-');
1967                 SCAT(string, "ST");
1968                 SCCAT(dial, 'c');
1969         }
1970
1971         /* error in dial string */
1972         if (!dial[0]) {
1973                 dial_error:
1974                 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_REQ, p_m_b_channel);
1975                 add_trace("string", NULL, "%s", p_dialinginfo.id);
1976                 if (!dial[0])
1977                         add_trace("error", NULL, "no number", dial);
1978                 else if (dial[0]!='a' && dial[0]!='b')
1979                         add_trace("error", NULL, "number must start with KP1/KP2", dial);
1980                 else
1981                         add_trace("error", NULL, "illegal format", dial);
1982                 end_trace();
1983                 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1984                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1985                 message->param.disconnectinfo.cause = CAUSE_INVALID;
1986                 message_put(message);
1987                 return;
1988         }
1989
1990         /* copy new dial string */
1991         SCPY(p_dialinginfo.id, dial);
1992
1993         /* attach only if not already */
1994         epointlist_new(epoint_id);
1995
1996         ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_REQ, p_m_b_channel);
1997         add_trace("string", NULL, "%s", string);
1998         add_trace("type", NULL, "%s", (dial[0]=='b')?"international":"national");
1999         add_trace("number", NULL, "%s", dial);
2000         end_trace();
2001         /* connect auto path */
2002         if ((p_m_mISDNport->ss5 & SS5_FEATURE_CONNECT)) {
2003                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
2004                 message_put(message);
2005         } else {
2006                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
2007                 message_put(message);
2008         }
2009
2010         /* start seizing */
2011         ss5_trace_header(p_m_mISDNport, this, SS5_SEIZING_REQ, p_m_b_channel);
2012         end_trace();
2013         new_ss5_state(SS5_STATE_SEIZING);
2014         new_ss5_signal(SS5_SIGNAL_SEND_ON);
2015         p_m_s_sample_nr = 0;
2016         inband_send_on();
2017
2018         p_type = PORT_TYPE_SS5_OUT;
2019         new_state(PORT_STATE_OUT_SETUP);
2020 }
2021
2022 /* MESSAGE_CONNECT */
2023 void Pss5::message_connect(unsigned int epoint_id, int message_id, union parameter *param)
2024 {
2025         memcpy(&p_connectinfo, &param->connectinfo, sizeof(p_connectinfo));
2026
2027         if (p_state != PORT_STATE_CONNECT) {
2028                 p_m_s_queued_signal = SS5_ANSWER_REQ;
2029                 new_state(PORT_STATE_CONNECT);
2030                 trigger_work(&p_m_s_queue);
2031         }
2032
2033         set_tone("", NULL);
2034 }
2035
2036 /* MESSAGE_DISCONNECT */
2037 void Pss5::message_disconnect(unsigned int epoint_id, int message_id, union parameter *param)
2038 {
2039         /* release and clear forward */
2040         if (p_type==PORT_TYPE_SS5_OUT) { /* outgoing exchange */
2041                 do_release(param->disconnectinfo.cause, param->disconnectinfo.location, SS5_CLEAR_FORWARD_REQ);
2042                 return;
2043         }
2044         /* release and clear back */
2045         if ((p_m_mISDNport->ss5 & SS5_FEATURE_RELEASE)) {
2046                 do_release(param->disconnectinfo.cause, param->disconnectinfo.location, SS5_CLEAR_BACK_REQ);
2047                 return;
2048         }
2049
2050         /* disconnect by sending clear back (after answer) or busy flash (before answer) */
2051         if (p_state != PORT_STATE_OUT_DISCONNECT) {
2052                 if (p_state == PORT_STATE_CONNECT)
2053                         p_m_s_queued_signal = SS5_CLEAR_BACK_REQ;
2054                 else
2055                         p_m_s_queued_signal = SS5_BUSY_FLASH_REQ;
2056                 new_state(PORT_STATE_OUT_DISCONNECT);
2057                 trigger_work(&p_m_s_queue);
2058         }
2059 }
2060
2061 /* MESSAGE_RELEASE */
2062 void Pss5::message_release(unsigned int epoint_id, int message_id, union parameter *param)
2063 {
2064         /* always send clear forward, because release guard only works as a reply to clear forward */
2065         do_release(param->disconnectinfo.cause, param->disconnectinfo.location, SS5_CLEAR_FORWARD_REQ);
2066 }
2067
2068 /*
2069  * endpoint sends messages to the port
2070  */
2071 int Pss5::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
2072 {
2073         if (PmISDN::message_epoint(epoint_id, message_id, param))
2074                 return(1);
2075
2076         switch(message_id) {
2077                 case MESSAGE_SETUP: /* dial-out command received from epoint */
2078                 if (p_state!=PORT_STATE_IDLE) {
2079                         PERROR("Pss5(%s) ignoring setup because isdn port is not in idle state (or connected for sending display info).\n", p_name);
2080                         break;
2081                 }
2082                 if (p_epointlist && p_state==PORT_STATE_IDLE)
2083                         FATAL("Pss5(%s): epoint pointer is set in idle state, how bad!!\n", p_name);
2084                 message_setup(epoint_id, message_id, param);
2085                 break;
2086
2087                 case MESSAGE_CONNECT: /* call of endpoint is connected */
2088                 message_connect(epoint_id, message_id, param);
2089                 break;
2090
2091                 case MESSAGE_DISCONNECT: /* call has been disconnected */
2092                 message_disconnect(epoint_id, message_id, param);
2093                 break;
2094
2095                 case MESSAGE_RELEASE: /* release isdn port */
2096                 message_release(epoint_id, message_id, param);
2097                 break;
2098
2099                 default:
2100                 PDEBUG(DEBUG_SS5, "Pss5(%s) ss5 port with (caller id %s) received an unhandled message: %d\n", p_name, p_callerinfo.id, message_id);
2101         }
2102
2103         return(1);
2104 }
2105