SS5: improvements
[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
535         again:
536         /* how much to copy ? */
537         tocopy = len - count;
538         space = SS5_DECODER_NPOINTS - p_m_s_decoder_count;
539         if (space < 0)
540                 FATAL("p_m_s_decoder_count overflows\n");
541         if (space < tocopy)
542                 tocopy = space;
543         /* copy an count */
544         memcpy(p_m_s_decoder_buffer+p_m_s_decoder_count, buffer+count, tocopy);
545         p_m_s_decoder_count += tocopy;
546         count += tocopy;
547         /* decoder buffer not completely filled ? */
548         if (tocopy < space)
549                 return;
550
551         /* decode one frame */
552         digit = ss5_decode(p_m_s_decoder_buffer, SS5_DECODER_NPOINTS, &quality);
553         p_m_s_decoder_count = 0;
554
555         /* indicate quality of received digit */
556         if ((p_m_mISDNport->ss5 & SS5_FEATURE_QUALITY)) {
557                 if (digit != ' ') {
558                         p_m_s_quality_value += quality;
559                         p_m_s_quality_count++;
560                 } else if (p_m_s_quality_count) {
561                         ss5_trace_header(p_m_mISDNport, this, SS5_QUALITY_IND, p_m_b_channel);
562                         add_trace("digit", NULL, "%c", p_m_s_last_digit);
563                         quality = p_m_s_quality_value/p_m_s_quality_count;
564                         add_trace("quality", NULL, "%3d%%", (int)(quality*100.0));
565                         end_trace();
566                         p_m_s_quality_value = 0;
567                         p_m_s_quality_count = 0;
568                 }
569         }
570
571 #ifdef DEBUG_DETECT
572         if (p_m_s_last_digit != digit && digit != ' ')
573                 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]);
574 #endif
575
576         /* ignore short loss of signal, or change within one decode window */
577         if (p_m_s_signal_loss) {
578                 if (digit == ' ') {
579                         /* still lost */
580                         if (p_m_s_signal_loss >= SS5_TIMER_SIGNAL_LOSS) {
581 #ifdef DEBUG_DETECT
582                                 PDEBUG(DEBUG_SS5, "%s: signal '%c' lost too long\n", p_name, p_m_s_last_digit);
583 #endif
584                                 /* long enough, we stop loss-timer */
585                                 p_m_s_signal_loss = 0;
586                         } else {
587                                 /* not long enough, so we use last signal */
588                                 p_m_s_signal_loss += SS5_DECODER_NPOINTS;
589                                 digit = p_m_s_last_digit;
590                         }
591                 } else {
592                         /* signal is back, we stop timer and store */
593 #ifdef DEBUG_DETECT
594                         PDEBUG(DEBUG_SS5, "%s: signal '%c' lost, but continues with '%c'\n", p_name, p_m_s_last_digit, digit);
595 #endif
596                         p_m_s_signal_loss = 0;
597                         p_m_s_last_digit = digit;
598                 }
599         } else {
600                 if (p_m_s_last_digit != ' ' && digit == ' ') {
601 #ifdef DEBUG_DETECT
602                         PDEBUG(DEBUG_SS5, "%s: signal '%c' lost\n", p_name, p_m_s_last_digit);
603 #endif
604                         /* restore last digit until signal is really lost */
605                         p_m_s_last_digit = digit;
606                         /* starting to loose signal */
607                         p_m_s_signal_loss = SS5_DECODER_NPOINTS;
608                 } else if (digit != p_m_s_last_digit) {
609                         /* digit changes, but we keep old digit until it is detected twice */
610 #ifdef DEBUG_DETECT
611                         PDEBUG(DEBUG_SS5, "%s: signal '%c' changes to '%c'\n", p_name, p_m_s_last_digit, digit);
612 #endif
613                         p_m_s_last_digit = digit;
614                         digit = p_m_s_last_digit_used;
615                 } else {
616                         /* storing last signal, in case it is lost */
617                         p_m_s_last_digit = digit;
618                 }
619         }
620         p_m_s_last_digit_used = digit;
621
622         /* update mute */
623         if ((p_m_mISDNport->ss5 & SS5_FEATURE_MUTE)) {
624                 int mdigit;
625                 memcpy(p_m_s_delay_mute, p_m_s_delay_mute+1, sizeof(p_m_s_delay_mute)-1);
626                 p_m_s_delay_mute[sizeof(p_m_s_delay_mute)-1] = digit;
627                 mdigit = p_m_s_delay_mute[0];
628                 if (p_m_mute) {
629                         /* mute is on */
630                         if (mdigit != 'A' && mdigit != 'B' && mdigit != 'C')
631                                 mute_off();
632                 } else {
633                         /* mute is off */
634                         if (mdigit == 'A' || mdigit == 'B' || mdigit == 'C')
635                                 mute_on();
636                 }
637         }
638
639         /* delay decoded tones */
640         if ((p_m_mISDNport->ss5 & SS5_FEATURE_DELAY)) {
641                 /* shift buffer */
642                 memcpy(p_m_s_delay_digits, p_m_s_delay_digits+1, sizeof(p_m_s_delay_digits)-1);
643                 /* first in */
644                 p_m_s_delay_digits[sizeof(p_m_s_delay_digits)-1] = digit;
645                 /* first out */
646                 digit = p_m_s_delay_digits[0];
647         }
648
649         /* clear forward is always recognized */
650         if (digit == 'C' && p_m_s_state != SS5_STATE_CLEAR_FORWARD && p_m_s_state != SS5_STATE_RELEASE_GUARD) {
651                 switch (p_type) {
652                         case PORT_TYPE_SS5_OUT:
653                         PDEBUG(DEBUG_SS5, "%s: received release-guard, waiting for recognition\n", p_name);
654                         break;
655                         case PORT_TYPE_SS5_IN:
656                         PDEBUG(DEBUG_SS5, "%s: received clear-forward, waiting for recognition\n", p_name);
657                         break;
658                         default:
659                         PDEBUG(DEBUG_SS5, "%s: received clear-forward in idle state, waiting for recognition\n", p_name);
660                         break;
661                 }
662                 new_ss5_state(SS5_STATE_RELEASE_GUARD);
663                 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
664                 p_m_s_recog = 0;
665         } else
666         switch(p_m_s_state) {
667                 case SS5_STATE_IDLE:
668                 /* seizing only recognized in port idle state */
669                 if (p_state == PORT_STATE_IDLE) {
670                         if (digit != 'A')
671                                 break;
672                         seize:
673                         PDEBUG(DEBUG_SS5, "%s: received seize, waiting for recognition\n", p_name);
674                         p_type = PORT_TYPE_SS5_IN;
675                         new_ss5_state(SS5_STATE_PROCEED_TO_SEND);
676                         new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
677                         p_m_s_recog = 0;
678                         break;
679                 }
680                 /* other signals */
681                 if (digit == 'A') {
682                         if (p_type != PORT_TYPE_SS5_OUT)
683                                 break;
684                         PDEBUG(DEBUG_SS5, "%s: received answer, waiting for recognition\n", p_name);
685                         new_ss5_state(SS5_STATE_ACK_ANSWER);
686                         new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
687                         p_m_s_recog = 0;
688                         break;
689                 }
690                 if (digit == 'B') {
691                         if (p_type == PORT_TYPE_SS5_IN) {
692                                 if ((p_m_mISDNport->ss5 & SS5_FEATURE_BELL)) {
693                                         new_ss5_state(SS5_STATE_DIAL_IN_PULSE); /* go pulsing state */
694                                         new_ss5_signal(SS5_SIGNAL_PULSE_OFF); /* we are starting with pulse off */
695                                         p_m_s_pulsecount = 0; /* init pulse counter */
696                                         p_m_s_dial[0] = '\0'; /* init dial string */
697                                         pulse_ind(1); /* also inits recogition timer... */
698                                         break;
699                                 }
700                                 PDEBUG(DEBUG_SS5, "%s: received forward-transfer, waiting for recognition\n", p_name);
701                                 /* forward transfer on incomming lines */
702                                 new_ss5_state(SS5_STATE_FORWARD_TRANSFER);
703                                 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
704                                 p_m_s_recog = 0;
705                                 break;
706                         }
707                         if (p_state == PORT_STATE_CONNECT) {
708                                 PDEBUG(DEBUG_SS5, "%s: received clear-back, waiting for recognition\n", p_name);
709                                 new_ss5_state(SS5_STATE_ACK_CLEAR_BACK);
710                         } else {
711                                 PDEBUG(DEBUG_SS5, "%s: received busy-flash, waiting for recognition\n", p_name);
712                                 new_ss5_state(SS5_STATE_ACK_BUSY_FLASH);
713                         }
714                         new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
715                         p_m_s_recog = 0;
716                         break;
717                 }
718                 /* dialing only allowed in incomming setup state */
719                 if (p_state == PORT_STATE_IN_SETUP) {
720                         if (!strchr("1234567890*#abc", digit))
721                                 break;
722                         PDEBUG(DEBUG_SS5, "%s: received dialing start with '%c'\n", p_name, digit);
723                         new_ss5_state(SS5_STATE_DIAL_IN);
724                         new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
725                         p_m_s_dial[0] = '\0';
726                         digit_ind(digit);
727                         break;
728                 }
729                 break;
730                 /* sending seizing */
731                 case SS5_STATE_SEIZING:
732                 switch (p_m_s_signal) {
733                         case SS5_SIGNAL_SEND_ON:
734                         if (digit == 'A') { /* double seize */
735                                 PDEBUG(DEBUG_SS5, "%s: received double seizure\n", p_name, digit);
736                                 double_seizure_ind();
737                                 break;
738                         }
739                         if (digit == 'B') {
740                                 PDEBUG(DEBUG_SS5, "%s: received answer to outgoing seize, waiting for recognition\n", p_name);
741                                 /* set recognition timer */
742                                 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
743                                 p_m_s_recog = 0;
744                         }
745                         break;
746                         case SS5_SIGNAL_SEND_ON_RECOG:
747                         if (digit != 'B') { /* seize */
748                                 PDEBUG(DEBUG_SS5, "%s: answer to outgoing seize is gone before recognition\n", p_name);
749                                 new_ss5_signal(SS5_SIGNAL_SEND_ON);
750 //                              p_m_s_sample_nr = 0;
751 //                              inband_send_on();
752                                 break;
753                         }
754                         p_m_s_recog += SS5_DECODER_NPOINTS;
755                         if (p_m_s_recog < SS5_TIMER_RECOG_SEIZE)
756                                 break;
757                         PDEBUG(DEBUG_SS5, "%s: answer to outgoing seize recognized, turning off, waiting for recognition\n", p_name);
758                         new_ss5_signal(SS5_SIGNAL_SEND_OFF);
759                         break;
760                         case SS5_SIGNAL_SEND_OFF:
761                         if (digit == 'B')
762                                 break;
763                         PDEBUG(DEBUG_SS5, "%s: outgoing seizure is complete, proceeding...\n", p_name);
764                         new_ss5_state(SS5_STATE_IDLE);
765                         proceed_to_send_ind();
766                         break;
767                 }
768                 break;
769                 /* answer to seize */
770                 case SS5_STATE_PROCEED_TO_SEND:
771                 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
772                         if (digit != 'A') {
773                                 PDEBUG(DEBUG_SS5, "%s: incomming seize is gone before recognition\n", p_name);
774                                 new_ss5_state(SS5_STATE_IDLE);
775                                 p_type = PORT_TYPE_SS5_IDLE;
776                                 break;
777                         }
778                         p_m_s_recog += SS5_DECODER_NPOINTS;
779                         if (p_m_s_recog < SS5_TIMER_RECOG_SEIZE)
780                                 break;
781                         PDEBUG(DEBUG_SS5, "%s: incomming seize is recognized, responding...\n", p_name);
782                         new_ss5_signal(SS5_SIGNAL_RECEIVE);
783                         p_m_s_sample_nr = 0;
784                         inband_send_on();
785                         break;
786                 }
787                 if (digit != 'A') {
788                         PDEBUG(DEBUG_SS5, "%s: incomming seize is gone after responding\n", p_name);
789                         new_ss5_state(SS5_STATE_IDLE);
790                         seizing_ind();
791                 }
792                 break;
793                 /* sending busy flash / answer / clear-back */
794                 case SS5_STATE_BUSY_FLASH:
795                 case SS5_STATE_ANSWER:
796                 case SS5_STATE_CLEAR_BACK:
797                 switch (p_m_s_signal) {
798                         case SS5_SIGNAL_SEND_ON:
799                         if (digit == 'A') {
800                                 PDEBUG(DEBUG_SS5, "%s: received acknowledge, waiting for recognition\n", p_name);
801                                 /* set recognition timer */
802                                 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
803                                 p_m_s_recog = 0;
804                         }
805                         break;
806                         case SS5_SIGNAL_SEND_ON_RECOG:
807                         if (digit != 'A') {
808                                 PDEBUG(DEBUG_SS5, "%s: acknowledge is gone before recognition\n", p_name);
809                                 new_ss5_signal(SS5_SIGNAL_SEND_ON);
810 //                              p_m_s_sample_nr = 0;
811 //                              inband_send_on();
812                                 break;
813                         }
814                         p_m_s_recog += SS5_DECODER_NPOINTS;
815                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
816                                 break;
817                         PDEBUG(DEBUG_SS5, "%s: acknowledge recognized, turning off, waiting for recognition\n", p_name);
818                         new_ss5_signal(SS5_SIGNAL_SEND_OFF);
819                         break;
820                         case SS5_SIGNAL_SEND_OFF:
821                         if (digit == 'A')
822                                 break;
823                         PDEBUG(DEBUG_SS5, "%s: outgoing signal is complete\n", p_name);
824                         new_ss5_state(SS5_STATE_IDLE);
825                         break;
826                 }
827                 break;
828                 /* answer to busy-flash / clear back */
829                 case SS5_STATE_ACK_BUSY_FLASH:
830                 case SS5_STATE_ACK_CLEAR_BACK:
831                 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
832                         if (digit != 'B') {
833                                 PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is gone before recognition\n", p_name);
834                                 new_ss5_state(SS5_STATE_IDLE);
835                                 break;
836                         }
837                         p_m_s_recog += SS5_DECODER_NPOINTS;
838                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
839                                 break;
840                         PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is recognized, responding...\n", p_name);
841                         new_ss5_signal(SS5_SIGNAL_RECEIVE);
842                         p_m_s_sample_nr = 0;
843                         inband_send_on();
844                         break;
845                 }
846                 if (digit != 'B') {
847                         PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is gone after responding\n", p_name);
848                         new_ss5_state(SS5_STATE_IDLE);
849                         if (p_m_s_state == SS5_STATE_ACK_BUSY_FLASH)
850                                 busy_flash_ind();
851                         else
852                                 clear_back_ind();
853                 }
854                 break;
855                 /* answer to answer */
856                 case SS5_STATE_ACK_ANSWER:
857                 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
858                         if (digit != 'A') {
859                                 PDEBUG(DEBUG_SS5, "%s: incomming answer is gone before recognition\n", p_name);
860                                 new_ss5_state(SS5_STATE_IDLE);
861                                 break;
862                         }
863                         p_m_s_recog += SS5_DECODER_NPOINTS;
864                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
865                                 break;
866                         PDEBUG(DEBUG_SS5, "%s: incomming answer is recognized, responding...\n", p_name);
867                         new_ss5_signal(SS5_SIGNAL_RECEIVE);
868                         p_m_s_sample_nr = 0;
869                         inband_send_on();
870                         break;
871                 }
872                 if (digit != 'A') {
873                         PDEBUG(DEBUG_SS5, "%s: incomming answer is gone after responding\n", p_name);
874                         new_ss5_state(SS5_STATE_IDLE);
875                         answer_ind();
876                 }
877                 break;
878                 /* sending clear-forward */
879                 case SS5_STATE_CLEAR_FORWARD:
880                 switch (p_m_s_signal) {
881                         case SS5_SIGNAL_SEND_ON:
882                         if (digit == 'C') {
883                                 PDEBUG(DEBUG_SS5, "%s: received answer to clear-forward, waiting for recognition\n", p_name);
884                                 /* set recognition timer */
885                                 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
886                                 p_m_s_recog = 0;
887                         }
888                         break;
889                         case SS5_SIGNAL_SEND_ON_RECOG:
890                         if (digit != 'C') {
891                                 PDEBUG(DEBUG_SS5, "%s: answer to clear-forward is gone before recognition\n", p_name);
892                                 new_ss5_signal(SS5_SIGNAL_SEND_ON);
893 //                              p_m_s_sample_nr = 0;
894 //                              inband_send_on();
895                                 break;
896                         }
897                         p_m_s_recog += SS5_DECODER_NPOINTS;
898                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
899                                 break;
900                         PDEBUG(DEBUG_SS5, "%s: answer to clear-forward recognized, turning off, waiting for recognition\n", p_name);
901                         new_ss5_signal(SS5_SIGNAL_SEND_OFF);
902                         break;
903                         case SS5_SIGNAL_SEND_OFF:
904                         if (digit == 'A') {
905                                 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward answer, continue with seize\n", p_name);
906                                 new_state(PORT_STATE_IDLE);
907                                 goto seize;
908                         }
909                         if (digit == 'C')
910                                 break;
911                         PDEBUG(DEBUG_SS5, "%s: answer to clear-forward is complete\n", p_name);
912                         release_guard_ind();
913                         new_ss5_signal(SS5_SIGNAL_DELAY);
914                         p_m_s_recog = 0; /* use recog to delay */
915                         PDEBUG(DEBUG_SS5, "%s: answer to clear-forward on outgoing interface starting delay to prevent ping-pong\n", p_name);
916                         break;
917                         case SS5_SIGNAL_DELAY:
918                         if (digit == 'A') {
919                                 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward answer, continue with seize\n", p_name);
920                                 new_state(PORT_STATE_IDLE);
921                                 goto seize;
922                         }
923                         p_m_s_recog += SS5_DECODER_NPOINTS;
924                         if (p_m_s_recog < SS5_TIMER_RELEASE_DELAY)
925                                 break;
926                         PDEBUG(DEBUG_SS5, "%s: delay time over, going idle\n", p_name);
927                         new_ss5_state(SS5_STATE_IDLE);
928                         new_state(PORT_STATE_IDLE);
929                         p_type = PORT_TYPE_SS5_IDLE;
930                         break;
931                 }
932                 break;
933                 /* answer to release-guard*/
934                 case SS5_STATE_RELEASE_GUARD:
935                 switch (p_m_s_signal) {
936                         case SS5_SIGNAL_RECEIVE_RECOG:
937                         if (digit != 'C') {
938                                 if (p_type == PORT_TYPE_SS5_OUT)
939                                         PDEBUG(DEBUG_SS5, "%s: incomming release-guard is gone before recognition\n", p_name);
940                                 else
941                                         PDEBUG(DEBUG_SS5, "%s: incomming clear forward is gone before recognition\n", p_name);
942                                 new_ss5_state(SS5_STATE_IDLE);
943                                 break;
944                         }
945                         p_m_s_recog += SS5_DECODER_NPOINTS;
946                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
947                                 break;
948                         if (p_type == PORT_TYPE_SS5_OUT)
949                                 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is recognized, responding...\n", p_name);
950                         else
951                                 PDEBUG(DEBUG_SS5, "%s: incomming clear-forward is recognized, responding...\n", p_name);
952                         new_state(PORT_STATE_RELEASE);
953                         new_ss5_signal(SS5_SIGNAL_RECEIVE);
954                         p_m_s_sample_nr = 0;
955                         inband_send_on();
956                         break;
957                         case SS5_SIGNAL_RECEIVE:
958                         if (digit == 'C'
959                          || p_m_s_sample_nr < 256) /* small hack to keep answer for at least some time */
960                          break;
961 #if 0
962                         if (digit == 'A') {
963                                 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward is received\n", p_name);
964                                 new_state(PORT_STATE_IDLE);
965                                 goto seize;
966                         }
967 #endif
968                         /* if clear forward stops right after recognition on the incomming side,
969                          * the release guard signal stops and may be too short to be recognized at the outgoing side.
970                          * to prevent this, a timer can be started to force a release guard that is long
971                          * enough to be recognized on the outgoing side.
972                          * this will prevent braking via blueboxing (other tricks may still be possible).
973                          */
974                         if ((p_m_mISDNport->ss5 & SS5_FEATURE_RELEASEGUARDTIMER)
975                          && p_m_s_sample_nr < SS5_TIMER_RELEASE_GUARD)
976                                 break;
977                         if (p_type == PORT_TYPE_SS5_OUT)
978                                 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is gone after responding\n", p_name);
979                         else
980                                 PDEBUG(DEBUG_SS5, "%s: incomming clear-forward is gone after responding\n", p_name);
981                         if (p_type == PORT_TYPE_SS5_OUT) {
982                                 release_guard_ind();
983                                 new_ss5_signal(SS5_SIGNAL_DELAY);
984                                 p_m_s_recog = 0; /* use recog to delay */
985                                 PDEBUG(DEBUG_SS5, "%s: incomming release-guard on outgoing interface starting delay to prevent ping-pong\n", p_name);
986                         } else {
987                                 clear_forward_ind();
988                                 new_ss5_state(SS5_STATE_IDLE);
989                         }
990                         break;
991                         case SS5_SIGNAL_DELAY:
992                         if (digit == 'A') {
993                                 PDEBUG(DEBUG_SS5, "%s: received seize right after release guard is gone, continue with seize\n", p_name);
994                                 new_state(PORT_STATE_IDLE);
995                                 goto seize;
996                         }
997                         p_m_s_recog += SS5_DECODER_NPOINTS;
998                         if (p_m_s_recog < SS5_TIMER_RELEASE_DELAY)
999                                 break;
1000                         PDEBUG(DEBUG_SS5, "%s: delay time over, going idle\n", p_name);
1001                         new_ss5_state(SS5_STATE_IDLE);
1002                         new_state(PORT_STATE_IDLE);
1003                         p_type = PORT_TYPE_SS5_IDLE;
1004                         break;
1005                 }
1006                 break;
1007                 /* wait time to recognize forward transfer */
1008                 case SS5_STATE_FORWARD_TRANSFER:
1009                 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
1010                         if (digit != 'B') {
1011                                 PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is gone before recognition\n", p_name);
1012                                 new_ss5_state(SS5_STATE_IDLE);
1013                                 break;
1014                         }
1015                         p_m_s_recog += SS5_DECODER_NPOINTS;
1016                         if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
1017                                 break;
1018                         PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is recognized, responding, if BELL feature was selected...\n", p_name);
1019                         new_ss5_signal(SS5_SIGNAL_RECEIVE);
1020 #if 0
1021                         p_m_s_sample_nr = 0;
1022                         inband_send_on();
1023 #endif
1024                         break;
1025                 }
1026                 if (digit != 'B') {
1027                         PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is gone after recognition\n", p_name);
1028                         new_ss5_state(SS5_STATE_IDLE);
1029                         forward_transfer_ind();
1030                         break;
1031                 }
1032                 break;
1033                 /* dialing is received */
1034                 case SS5_STATE_DIAL_IN:
1035                 if (strchr("1234567890*#abc", digit)) {
1036                         if (p_m_s_signal != SS5_SIGNAL_DIGIT_PAUSE)
1037                                 break;
1038                         PDEBUG(DEBUG_SS5, "%s: incomming digit '%c' is recognized\n", p_name, digit);
1039                         new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1040                         digit_ind(digit);
1041                 } else {
1042                         if (p_m_s_signal != SS5_SIGNAL_DIGIT_ON)
1043                                 break;
1044                         PDEBUG(DEBUG_SS5, "%s: incomming digit is gone after recognition\n", p_name);
1045                         new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
1046                 }
1047                 break;
1048                 case SS5_STATE_DIAL_IN_PULSE:
1049                 if (digit == 'B')
1050                         pulse_ind(1);
1051                 else
1052                         pulse_ind(0);
1053                 break;
1054         }
1055
1056         /* something more to decode ? */
1057         if (count != len)
1058                 goto again;
1059 }
1060
1061
1062 /*
1063  * signalling sender
1064  *
1065  * this function generates tones and assembles dial string with digits and pause
1066  * the result is sent to mISDN. it uses the ss5_encode() function.
1067  * except for dialing and forward-transfer, tones are continuous and will not change state.
1068  */
1069 int Pss5::inband_send(unsigned char *buffer, int len)
1070 {
1071         int count = 0; /* sample counter */
1072         int duration;
1073         char digit;
1074         int tocode, tosend;
1075
1076         switch(p_m_s_state) {
1077                 /* turn off transmitter in idle state */
1078                 case SS5_STATE_IDLE:
1079                 inband_send_off();
1080                 break;
1081
1082                 case SS5_STATE_SEIZING:
1083                 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1084                  && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1085                         break;
1086                 duration = -1; /* continuous */
1087                 digit = 'A';
1088                 send:
1089                 /* how much samples do we have left */
1090                 if (duration < 0)
1091                         tocode = len;
1092                 else
1093                         tocode = duration - p_m_s_sample_nr;
1094                 if (tocode > 0) {
1095                         if (tocode > len)
1096                                 tocode = len;
1097                         ss5_encode(buffer, tocode, digit, p_m_s_sample_nr);
1098                         /* increase counters */
1099                         p_m_s_sample_nr += tocode;
1100                         count += tocode;
1101                 }
1102                 /* more to come ? */
1103                 if (duration > 0 && p_m_s_sample_nr >= duration) {
1104                         PDEBUG(DEBUG_SS5, "%s: sending tone '%c' complete, starting delay\n", p_name, digit);
1105                         if (p_m_s_state == SS5_STATE_DOUBLE_SEIZE) {
1106                                 do_release(CAUSE_NOCHANNEL, LOCATION_PRIVATE_LOCAL, SS5_CLEAR_FORWARD_REQ);
1107                                 break;
1108                         }
1109                         new_ss5_state(SS5_STATE_DELAY);
1110                         p_m_s_sample_nr = 0;
1111                 }
1112 #if 0
1113                 /* stop sending if too long */
1114                 if (duration < 0 && p_m_s_sample_nr >= SS5_TIMER_MAX_SIGNAL) {
1115                         PDEBUG(DEBUG_SS5, "%s: sending tone '%c' too long, stopping\n", p_name, digit);
1116                         inband_send_off();
1117                         break;
1118                 }
1119 #endif
1120                 break;
1121                 /* incomming seizing */
1122                 case SS5_STATE_PROCEED_TO_SEND:
1123                 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1124                         break;
1125                 duration = -1; /* continuous */
1126                 digit = 'B';
1127                 goto send;
1128
1129                 case SS5_STATE_BUSY_FLASH:
1130                 case SS5_STATE_CLEAR_BACK:
1131                 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1132                  && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1133                         break;
1134                 duration = -1; /* continuous */
1135                 digit = 'B';
1136                 goto send;
1137
1138                 case SS5_STATE_ANSWER:
1139                 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1140                  && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1141                         break;
1142                 duration = -1; /* continuous */
1143                 digit = 'A';
1144                 goto send;
1145
1146                 case SS5_STATE_ACK_BUSY_FLASH:
1147                 case SS5_STATE_ACK_ANSWER:
1148                 case SS5_STATE_ACK_CLEAR_BACK:
1149                 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1150                         break;
1151                 duration = -1; /* continuous */
1152                 digit = 'A';
1153                 goto send;
1154
1155 #if 0
1156                 case SS5_STATE_FORWARD_TRANSFER:
1157                 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1158                         break;
1159                 /* only on bell systems continue and acknowledge tone */
1160                 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_BELL))
1161                         break;
1162                 duration = SS5_TIMER_FORWARD;
1163                 digit = 'B';
1164                 goto send;
1165 #endif
1166
1167                 case SS5_STATE_CLEAR_FORWARD:
1168                 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1169                  && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1170                         break;
1171                 duration = -1; /* continuous */
1172                 digit = 'C';
1173                 goto send;
1174
1175                 case SS5_STATE_RELEASE_GUARD:
1176                 if (p_m_s_signal != SS5_SIGNAL_RECEIVE
1177                  && p_m_s_signal != SS5_SIGNAL_DELAY)
1178                         break;
1179                 /* prevent from sending release guard too long */
1180                 if (p_m_s_sample_nr >= SS5_TIMER_RELEASE_MAX)
1181                         break;
1182                 duration = -1; /* continuous */
1183                 digit = 'C';
1184                 goto send;
1185
1186                 case SS5_STATE_DIAL_OUT:
1187                 if ((p_m_mISDNport->ss5 & SS5_FEATURE_PULSEDIALING))
1188                         count = inband_dial_pulse(buffer, len, count);
1189                 else
1190                         count = inband_dial_mf(buffer, len, count);
1191                 break;
1192                 break;
1193
1194                 case SS5_STATE_DELAY:
1195                 tosend = len - count;
1196                 memset(buffer+count, audio_s16_to_law[0], tosend);
1197                 p_m_s_sample_nr += tosend;
1198                 count += tosend;
1199                 if (p_m_s_sample_nr >= SS5_TIMER_AFTER_SIGNAL) {
1200                         PDEBUG(DEBUG_SS5, "%s: delay done, ready for next signal\n", p_name);
1201                         new_ss5_state(SS5_STATE_IDLE);
1202                         inband_send_off();
1203                 }
1204                 break;
1205
1206                 case SS5_STATE_DOUBLE_SEIZE:
1207                 duration = SS5_TIMER_DOUBLE_SEIZE;
1208                 digit = 'A';
1209                 goto send;
1210
1211                 /* nothing to send */
1212                 default:
1213                 PERROR("inband signalling is turned on, but no signal is processed here.");
1214                 new_ss5_state(SS5_STATE_IDLE);
1215                 inband_send_off();
1216                 return 0;
1217         }
1218
1219         /* return (partly) filled buffer */
1220         return count;
1221 }
1222
1223
1224 int Pss5::inband_dial_mf(unsigned char *buffer, int len, int count)
1225 {
1226         int duration;
1227         int tocode, tosend;
1228         char digit;
1229
1230         /* dialing
1231          *
1232          * p_m_s_dial: digits to be dialed
1233          * p_m_s_digit_i: current digit counter
1234          * p_m_s_signal: current signal state
1235          * p_m_s_sample_nr: current sample number
1236          */
1237         again:
1238         /* get digit and duration */
1239         digit = p_m_s_dial[p_m_s_digit_i];
1240         if (!digit) { /* if end of string reached */
1241                 new_ss5_state(SS5_STATE_DELAY);
1242                 p_m_s_sample_nr = 0;
1243                 return count;
1244         }
1245         if (p_m_s_signal == SS5_SIGNAL_DIGIT_ON) {
1246                 if (!p_m_s_digit_i) // first digit
1247                         duration = SS5_TIMER_KP;
1248                 else
1249                         duration = SS5_TIMER_DIGIT;
1250         } else {
1251                 duration = SS5_TIMER_PAUSE;
1252         }
1253         /* end of digit/pause ? */
1254         if (p_m_s_sample_nr >= duration) {
1255                 p_m_s_sample_nr = 0;
1256                 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE)
1257                         new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1258                 else {
1259                         new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
1260                         p_m_s_digit_i++;
1261                         goto again;
1262                 }
1263         }
1264         /* how much samples do we have left */
1265         tosend = len - count;
1266         tocode = duration - p_m_s_sample_nr;
1267         if (tocode < 0)
1268                 FATAL("sample_nr overrun duration");
1269         if (tosend < tocode)
1270                 tocode = tosend;
1271         /* digit or pause */
1272         if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE) {
1273                 memset(buffer+count, audio_s16_to_law[0], tocode);
1274 //              printf("coding pause %d bytes\n", tocode);
1275         } else {
1276                 ss5_encode(buffer+count, tocode, digit, p_m_s_sample_nr);
1277 //              printf("coding digit '%c' %d bytes\n", digit, tocode);
1278         }
1279         /* increase counters */
1280         p_m_s_sample_nr += tocode;
1281         count += tocode;
1282         /* can we take more ? */
1283         if (len != count)
1284                 goto again;
1285         return count;
1286 }
1287
1288
1289 int Pss5::inband_dial_pulse(unsigned char *buffer, int len, int count)
1290 {
1291         int tocode, tosend;
1292         int duration;
1293         char digit;
1294
1295         /* dialing
1296          *
1297          * p_m_s_dial: digits to be dialed
1298          * p_m_s_digit_i: current digit counter
1299          * p_m_s_signal: current signal state
1300          * p_m_s_sample_nr: current sample number
1301          */
1302         again:
1303         /* get digit */
1304         digit = p_m_s_dial[p_m_s_digit_i];
1305         if (!digit) { /* if end of string reached */
1306                 new_ss5_state(SS5_STATE_DELAY);
1307                 p_m_s_sample_nr = 0;
1308                 return count;
1309         }
1310         /* convert digit to pulse */
1311         switch (digit) {
1312                 case '1':
1313                 case '2':
1314                 case '3':
1315                 case '4':
1316                 case '5':
1317                 case '6':
1318                 case '7':
1319                 case '8':
1320                 case '9':
1321                 digit -= '0';
1322                 break;
1323                 case '0':
1324                 digit = 10;
1325                 break;
1326                 case '*':
1327                 digit = 11;
1328                 break;
1329                 case '#':
1330                 digit = 12;
1331                 break;
1332                 default:
1333                 p_m_s_digit_i++;
1334                 goto again;
1335         }
1336         /* get duration */
1337         if (p_m_s_signal == SS5_SIGNAL_DIGIT_ON) {
1338                 if (p_m_s_pulsecount & 1)
1339                         duration = BELL_TIMER_MAKE; /* loop closed */
1340                 else
1341                         duration = BELL_TIMER_BREAK; /* loop open, tone */
1342         } else {
1343                 duration = BELL_TIMER_PAUSE;
1344         }
1345         /* end of digit/pause ? */
1346         if (p_m_s_sample_nr >= duration) {
1347                 p_m_s_sample_nr = 0;
1348                 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE) {
1349                         new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1350                         PDEBUG(DEBUG_SS5, "%s: starting pusling digit '%c'\n", p_name, digit);
1351                 } else {
1352                         p_m_s_pulsecount++; /* toggle pulse */
1353                         if (!(p_m_s_pulsecount & 1)) {
1354                                 /* pulse now on again, but if end is reached... */
1355                                 if (p_m_s_pulsecount == (digit<<1)) {
1356                                         new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
1357                                         p_m_s_pulsecount = 0;
1358                                         p_m_s_digit_i++;
1359                                         goto again;
1360                                 }
1361                         }
1362                 }
1363         }
1364         /* how much samples do we have left */
1365         tosend = len - count;
1366         tocode = duration - p_m_s_sample_nr;
1367         if (tocode < 0)
1368                 FATAL("sample_nr overrun duration");
1369         if (tosend < tocode)
1370                 tocode = tosend;
1371         /* digit or pause */
1372         if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE
1373          || (p_m_s_pulsecount&1)) /* ...or currently on and no pulse */
1374                 memset(buffer+count, audio_s16_to_law[0], tocode);
1375         else
1376                 ss5_encode(buffer+count, tocode, 'B', p_m_s_sample_nr);
1377         /* increase counters */
1378         p_m_s_sample_nr += tocode;
1379         count += tocode;
1380         /* can we take more ? */
1381         if (len != count)
1382                 goto again;
1383         return count;
1384 }
1385
1386
1387 /*
1388  * start signal
1389  */ 
1390 void Pss5::start_signal(int state)
1391 {
1392         PDEBUG(DEBUG_SS5, "%s: starting singal '%s'\n", p_name, ss5_state_name[state]);
1393         /* start signal */
1394         new_ss5_state(state);
1395         if (state == SS5_STATE_DIAL_OUT) {
1396                 p_m_s_digit_i = 0;
1397                 p_m_s_pulsecount = 0;
1398                 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1399         } else
1400                 new_ss5_signal(SS5_SIGNAL_SEND_ON);
1401
1402         /* double seize must continue the current seize tone, so don't reset sample_nr */
1403         if (state != SS5_STATE_DOUBLE_SEIZE) {
1404                 /* (re)set sound phase to 0 */
1405                 p_m_s_sample_nr = 0;
1406         }
1407
1408         /* turn on inband transmitter */
1409         inband_send_on();
1410 }
1411
1412
1413 /*
1414  * handles all indications
1415  */
1416 void Pss5::seizing_ind(void)
1417 {
1418         ss5_trace_header(p_m_mISDNport, this, SS5_SEIZING_IND, p_m_b_channel);
1419         end_trace();
1420
1421         new_state(PORT_STATE_IN_SETUP);
1422         set_tone("", "noise");
1423 }
1424
1425 void Pss5::digit_ind(char digit)
1426 {
1427         int i;
1428         char string[128] = "", dial[128] = "";
1429         int dash, first_digit, last_was_digit;
1430
1431         /* add digit */
1432         SCCAT(p_m_s_dial, digit);
1433
1434         if (p_state == PORT_STATE_IN_SETUP)
1435                 new_state(PORT_STATE_IN_OVERLAP);
1436
1437         /* not last digit ? */
1438         if (digit != 'c')
1439                 return;
1440
1441         /* parse string */
1442         dash = 0; /* dash must be used next time */
1443         first_digit = 1;
1444         last_was_digit = 0;
1445         p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
1446         for (i = 0; p_m_s_dial[i]; i++) {
1447                 if (dash || (last_was_digit && (p_m_s_dial[i]<'0' || p_m_s_dial[i]>'9')))
1448                         SCCAT(string, '-');
1449                 dash = 0;
1450                 last_was_digit = 0;
1451                 switch(p_m_s_dial[i]) {
1452                         case '1':
1453                         case '2':
1454                         case '3':
1455                         case '4':
1456                         case '5':
1457                         case '6':
1458                         case '7':
1459                         case '8':
1460                         case '9':
1461                         case '0':
1462                         if (first_digit)
1463                                 dash = 1;
1464                         first_digit = 0;
1465                         last_was_digit = 1;
1466                         SCCAT(string, p_m_s_dial[i]);
1467                         SCCAT(dial, p_m_s_dial[i]);
1468                         break;
1469                         case '*':
1470                         SCAT(string, "C11");
1471                         SCCAT(dial, p_m_s_dial[i]);
1472                         dash = 1;
1473                         break;
1474                         case '#':
1475                         SCAT(string, "C12");
1476                         SCCAT(dial, p_m_s_dial[i]);
1477                         dash = 1;
1478                         break;
1479                         case 'a':
1480                         SCAT(string, "KP1");
1481                         SCCAT(dial, p_m_s_dial[i]);
1482                         dash = 1;
1483                         break;
1484                         case 'b':
1485                         SCAT(string, "KP2");
1486                         SCCAT(dial, p_m_s_dial[i]);
1487                         dash = 1;
1488                         break;
1489                         case 'c':
1490                         SCAT(string, "ST");
1491                         dash = 1;
1492                         break;
1493                         default:
1494                         break;
1495                 }
1496         }
1497         ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1498         add_trace("string", NULL, "%s", string);
1499         add_trace("number", NULL, "%s", dial);
1500         end_trace();
1501         new_ss5_state(SS5_STATE_IDLE);
1502
1503         do_setup(dial, 1);
1504         new_state(PORT_STATE_IN_PROCEEDING);
1505 }
1506
1507 void Pss5::pulse_ind(int on)
1508 {
1509         struct lcr_msg *message;
1510         char dial[3] = "a.";
1511
1512         if (p_m_s_signal == SS5_SIGNAL_PULSE_OFF) {
1513                 if (on) {
1514                         /* pulse turns on */
1515                         p_m_s_recog = 0;
1516                         new_ss5_signal(SS5_SIGNAL_PULSE_ON);
1517                         /* pulse turns of, count it */
1518                         p_m_s_pulsecount++;
1519                         PDEBUG(DEBUG_SS5, "%s: pulse turns on, counting\n", p_name);
1520                 } else {
1521                         /* pulse remains off */
1522                         p_m_s_recog += SS5_DECODER_NPOINTS;
1523                         /* not recognized end of digit, we wait... */
1524                         if (p_m_s_recog < BELL_TIMER_RECOG_END)
1525                                 return;
1526                         PDEBUG(DEBUG_SS5, "%s: pulse remains off, counted %d pulses\n", p_name, p_m_s_pulsecount);
1527                         if (p_m_s_pulsecount >= 12)
1528                                 dial[1] = '#';
1529                         else if (p_m_s_pulsecount == 11)
1530                                 dial[1] = '*';
1531                         else if (p_m_s_pulsecount == 10)
1532                                 dial[1] = '0';
1533                         else
1534                                 dial[1] = p_m_s_pulsecount + '0';
1535                         ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1536                         add_trace("digit", NULL, "%s", dial+1);
1537                         add_trace("pulses", NULL, "%d", p_m_s_pulsecount);
1538                         end_trace();
1539                         if (p_state == PORT_STATE_IN_SETUP) {
1540                                 /* sending digit as setup */
1541                                 do_setup(dial, 0); /* include 'a' == KP1 */
1542                                 new_state(PORT_STATE_IN_OVERLAP);
1543                         } else {
1544                                 /* sending digit as information */
1545                                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_INFORMATION);
1546                                 SCPY(message->param.information.id, dial+1);
1547                                 message_put(message);
1548                         }
1549                                 new_ss5_state(SS5_STATE_IDLE);
1550                         /* done rx pulses, return to idle */
1551                         new_ss5_state(SS5_STATE_IDLE);
1552                 }
1553         } else {
1554                 if (on) {
1555                         /* pulse remains on */
1556                         p_m_s_recog += SS5_DECODER_NPOINTS;
1557                 } else {
1558                         /* pulse turns off */
1559                         if (p_m_s_recog >= BELL_TIMER_RECOG_HANGUP) {
1560                                 PDEBUG(DEBUG_SS5, "%s: long pulse turns off, releasing\n", p_name);
1561                                 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1562                                 add_trace("longtone", NULL, "releases call");
1563                                 end_trace();
1564                                 /* long pulse is gone, release current connection, if any */
1565                                 while(p_epointlist) {
1566                                         message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1567                                         message->param.disconnectinfo.location = LOCATION_BEYOND;
1568                                         message->param.disconnectinfo.cause = CAUSE_NORMAL;
1569                                         message_put(message);
1570                                         free_epointlist(p_epointlist);
1571                                 }
1572                                 set_tone("", NULL);
1573                                 /* return to setup state */
1574                                 new_state(PORT_STATE_IN_SETUP);
1575                                 new_ss5_state(SS5_STATE_IDLE);
1576                                 return;
1577                         }
1578                         PDEBUG(DEBUG_SS5, "%s: short pulse turns off, releasing\n", p_name);
1579                         p_m_s_recog = 0;
1580                         new_ss5_signal(SS5_SIGNAL_PULSE_OFF);
1581                 }
1582         }
1583 }
1584
1585 void Pss5::proceed_to_send_ind(void)
1586 {
1587         ss5_trace_header(p_m_mISDNport, this, SS5_PROCEED_TO_SEND_IND, p_m_b_channel);
1588         end_trace();
1589
1590         SCPY(p_m_s_dial, p_dialinginfo.id);
1591         start_signal(SS5_STATE_DIAL_OUT);
1592
1593         new_state(PORT_STATE_OUT_OVERLAP);
1594 }
1595
1596 void Pss5::busy_flash_ind(void)
1597 {
1598         struct lcr_msg *message;
1599
1600         ss5_trace_header(p_m_mISDNport, this, SS5_BUSY_FLASH_IND, p_m_b_channel);
1601         end_trace();
1602
1603         /* busy before dialing ? */
1604         if (!p_epointlist)
1605                 return;
1606
1607         if (!(p_m_mISDNport->ss5 & SS5_FEATURE_NODISCONNECT)) {
1608                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DISCONNECT);
1609                 message->param.disconnectinfo.location = LOCATION_BEYOND;
1610                 message->param.disconnectinfo.cause = CAUSE_BUSY;
1611                 message_put(message);
1612         }
1613
1614         new_state(PORT_STATE_IN_DISCONNECT);
1615 }
1616
1617 void Pss5::answer_ind(void)
1618 {
1619         struct lcr_msg *message;
1620
1621         ss5_trace_header(p_m_mISDNport, this, SS5_ANSWER_IND, p_m_b_channel);
1622         end_trace();
1623
1624         /* answer before dialing ? */
1625         if (!p_epointlist)
1626                 return;
1627
1628         /* already connected */
1629         if (!(p_m_mISDNport->ss5 & SS5_FEATURE_CONNECT)) {
1630                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
1631                 message_put(message);
1632         }
1633
1634         new_state(PORT_STATE_CONNECT);
1635 }
1636
1637 void Pss5::forward_transfer_ind(void)
1638 {
1639 //      struct lcr_msg *message;
1640
1641         ss5_trace_header(p_m_mISDNport, this, SS5_FORWARD_TRANSFER_IND, p_m_b_channel);
1642         end_trace();
1643
1644 #if 0
1645         /* if BELL flavor bluebox flag is set, use it to seize a new line */
1646         if (!(p_m_mISDNport->ss5 & SS5_FEATURE_BELL))
1647                 return;
1648
1649         /* special BELL flavor hack to clear a line and seize a new one */
1650         while(p_epointlist) {
1651                 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1652                 message->param.disconnectinfo.location = LOCATION_BEYOND;
1653                 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1654                 message_put(message);
1655                 free_epointlist(p_epointlist);
1656         }
1657         set_tone("", NULL);
1658         new_state(PORT_STATE_IN_SETUP);
1659 #endif
1660 }
1661
1662 void Pss5::clear_back_ind(void)
1663 {
1664         struct lcr_msg *message;
1665
1666         ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_BACK_IND, p_m_b_channel);
1667         end_trace();
1668
1669         /* nobody? */
1670         if (!p_epointlist)
1671                 return;
1672
1673         if (!(p_m_mISDNport->ss5 & SS5_FEATURE_NODISCONNECT)) {
1674                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DISCONNECT);
1675                 message->param.disconnectinfo.location = LOCATION_BEYOND;
1676                 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1677                 message_put(message);
1678         }
1679
1680         new_state(PORT_STATE_IN_DISCONNECT);
1681 }
1682
1683 void Pss5::clear_forward_ind(void)
1684 {
1685         struct lcr_msg *message;
1686
1687         ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_FORWARD_IND, p_m_b_channel);
1688         end_trace();
1689
1690         new_state(PORT_STATE_IDLE);
1691         set_tone("", NULL);
1692         p_type = PORT_TYPE_SS5_IDLE;
1693
1694         /* someone ? */
1695         if (!p_epointlist)
1696                 return;
1697
1698         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1699         message->param.disconnectinfo.location = LOCATION_BEYOND;
1700         message->param.disconnectinfo.cause = CAUSE_NORMAL;
1701         message_put(message);
1702         free_epointlist(p_epointlist);
1703
1704 }
1705
1706 void Pss5::release_guard_ind(void)
1707 {
1708         struct lcr_msg *message;
1709
1710         ss5_trace_header(p_m_mISDNport, this, SS5_RELEASE_GUARD_IND, p_m_b_channel);
1711         end_trace();
1712
1713         set_tone("", NULL);
1714
1715         /* someone ? */
1716         if (!p_epointlist)
1717                 return;
1718
1719         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1720         message->param.disconnectinfo.location = LOCATION_BEYOND;
1721         message->param.disconnectinfo.cause = CAUSE_NORMAL;
1722         message_put(message);
1723         free_epointlist(p_epointlist);
1724 }
1725
1726 void Pss5::double_seizure_ind(void)
1727 {
1728         ss5_trace_header(p_m_mISDNport, this, SS5_DOUBLE_SEIZURE_IND, p_m_b_channel);
1729         end_trace();
1730         ss5_trace_header(p_m_mISDNport, this, SS5_DOUBLE_SEIZURE_REQ, p_m_b_channel);
1731         end_trace();
1732
1733         /* start double seizure sequence, so remote exchange will recognize it */
1734         start_signal(SS5_STATE_DOUBLE_SEIZE);
1735 }
1736
1737
1738 /*
1739  * shuts down by sending a clear forward and releasing endpoint
1740  */
1741 void Pss5::do_release(int cause, int location, int signal)
1742 {
1743         struct lcr_msg *message;
1744
1745         /* sending release to endpoint */
1746         while(p_epointlist) {
1747                 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1748                 message->param.disconnectinfo.location = location;
1749                 message->param.disconnectinfo.cause = cause;
1750                 message_put(message);
1751                 free_epointlist(p_epointlist);
1752         }
1753
1754 //      if (p_state != PORT_STATE_RELEASE) {
1755                 p_m_s_queued_signal = signal;
1756                 if (signal == SS5_CLEAR_FORWARD_REQ) {
1757                         new_state(PORT_STATE_RELEASE);
1758                         set_tone("", "noise");
1759                 } else
1760                         new_state(PORT_STATE_OUT_DISCONNECT);
1761                 trigger_work(&p_m_s_queue);
1762 //      }
1763 }
1764
1765
1766 /*
1767  * create endpoint and send setup
1768  */
1769 void Pss5::do_setup(char *dial, int complete)
1770 {
1771         class Endpoint *epoint;
1772         struct lcr_msg *message;
1773
1774         SCPY(p_dialinginfo.id, dial);
1775         p_dialinginfo.sending_complete = complete;
1776         p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
1777         p_callerinfo.screen = INFO_SCREEN_NETWORK;
1778         p_callerinfo.ntype = INFO_NTYPE_NOTPRESENT;
1779         p_callerinfo.isdn_port = p_m_portnum;
1780         SCPY(p_callerinfo.interface, p_m_mISDNport->ifport->interface->name);
1781
1782         p_capainfo.bearer_capa = INFO_BC_AUDIO;
1783         p_capainfo.bearer_info1 = (options.law=='a')?3:2;
1784         p_capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
1785         p_capainfo.hlc = INFO_HLC_NONE;
1786         p_capainfo.exthlc = INFO_HLC_NONE;
1787         p_capainfo.source_mode = B_MODE_TRANSPARENT;
1788
1789         /* create endpoint */
1790         if (p_epointlist)
1791                 FATAL("Incoming call but already got an endpoint.\n");
1792         if (!(epoint = new Endpoint(p_serial, 0)))
1793                 FATAL("No memory for Endpoint instance\n");
1794         epoint->ep_app = new_endpointapp(epoint, 0, p_m_mISDNport->ifport->interface->app); //incoming
1795         epointlist_new(epoint->ep_serial);
1796
1797         /* send setup message to endpoit */
1798         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
1799         message->param.setup.isdn_port = p_m_portnum;
1800         message->param.setup.port_type = p_type;
1801 //      message->param.setup.dtmf = !p_m_mISDNport->ifport->nodtmf;
1802         memcpy(&message->param.setup.dialinginfo, &p_dialinginfo, sizeof(struct dialing_info));
1803         memcpy(&message->param.setup.callerinfo, &p_callerinfo, sizeof(struct caller_info));
1804         memcpy(&message->param.setup.redirinfo, &p_redirinfo, sizeof(struct redir_info));
1805         memcpy(&message->param.setup.capainfo, &p_capainfo, sizeof(struct capa_info));
1806         message_put(message);
1807
1808 }
1809
1810
1811
1812 /*
1813  * handles all messages from endpoint
1814  */
1815
1816 /* MESSAGE_SETUP */
1817 void Pss5::message_setup(unsigned int epoint_id, int message_id, union parameter *param)
1818 {
1819         struct lcr_msg *message;
1820         int i;
1821         char string[128] = "", dial[128] = "";
1822         int dash, first_digit, last_was_digit;
1823
1824         if (p_epointlist) {
1825                 PERROR("endpoint already exist.\n");
1826                 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1827                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1828                 message->param.disconnectinfo.cause = CAUSE_UNSPECIFIED;
1829                 message_put(message);
1830                 return;
1831         }
1832
1833         /* copy setup infos to port */
1834         memcpy(&p_callerinfo, &param->setup.callerinfo, sizeof(p_callerinfo));
1835         memcpy(&p_dialinginfo, &param->setup.dialinginfo, sizeof(p_dialinginfo));
1836         memcpy(&p_capainfo, &param->setup.capainfo, sizeof(p_capainfo));
1837         memcpy(&p_redirinfo, &param->setup.redirinfo, sizeof(p_redirinfo));
1838         /* screen outgoing caller id */
1839         do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_m_mISDNport->ifport->interface->name);
1840         do_screen(1, p_callerinfo.id2, sizeof(p_callerinfo.id2), &p_callerinfo.ntype2, &p_callerinfo.present2, p_m_mISDNport->ifport->interface->name);
1841
1842         /* parse dial string  */
1843         dash = 0; /* dash must be used next time */
1844         first_digit = 1;
1845         last_was_digit = 0;
1846         for (i = 0; p_dialinginfo.id[i]; i++) {
1847                 if (dash || (last_was_digit && (p_dialinginfo.id[i]<'0' || p_dialinginfo.id[i]>'9')))
1848                         SCCAT(string, '-');
1849                 dash = 0;
1850                 last_was_digit = 0;
1851                 switch(p_dialinginfo.id[i]) {
1852                         case '1':
1853                         case '2':
1854                         case '3':
1855                         case '4':
1856                         case '5':
1857                         case '6':
1858                         case '7':
1859                         case '8':
1860                         case '9':
1861                         case '0':
1862                         if (i && first_digit)
1863                                 dash = 1;
1864                         first_digit = 0;
1865                         last_was_digit = 1;
1866                         SCCAT(string, p_dialinginfo.id[i]);
1867                         SCCAT(dial, p_dialinginfo.id[i]);
1868                         break;
1869                         case '*':
1870                         SCAT(string, "C11");
1871                         SCCAT(dial, '*');
1872                         dash = 1;
1873                         break;
1874                         case '#':
1875                         SCAT(string, "C12");
1876                         SCCAT(dial, '#');
1877                         dash = 1;
1878                         break;
1879                         case 'a':
1880                         SCAT(string, "KP1");
1881                         SCCAT(dial, 'a');
1882                         dash = 1;
1883                         break;
1884                         case 'b':
1885                         SCAT(string, "KP2");
1886                         SCCAT(dial, 'b');
1887                         dash = 1;
1888                         break;
1889                         case 'c':
1890                         SCAT(string, "ST");
1891                         SCCAT(dial, 'c');
1892                         dash = 1;
1893                         case 'K':
1894                         i++;
1895                         if (p_dialinginfo.id[i] != 'P')
1896                                 goto dial_error;
1897                         i++;
1898                         if (p_dialinginfo.id[i] == '1') {
1899                                 SCAT(string, "KP1");
1900                                 SCCAT(dial, 'a');
1901                                 dash = 1;
1902                                 break;
1903                         }
1904                         if (p_dialinginfo.id[i] == '2') {
1905                                 SCAT(string, "KP2");
1906                                 SCCAT(dial, 'b');
1907                                 dash = 1;
1908                                 break;
1909                         }
1910                         goto dial_error;
1911                         case 'C':
1912                         i++;
1913                         if (p_dialinginfo.id[i] != '1')
1914                                 goto dial_error;
1915                         i++;
1916                         if (p_dialinginfo.id[i] == '1') {
1917                                 SCAT(string, "C11");
1918                                 SCCAT(dial, 'a');
1919                                 dash = 1;
1920                                 break;
1921                         }
1922                         if (p_dialinginfo.id[i] == '2') {
1923                                 SCAT(string, "C12");
1924                                 SCCAT(dial, 'b');
1925                                 dash = 1;
1926                                 break;
1927                         }
1928                         goto dial_error;
1929                         case 'S':
1930                         i++;
1931                         if (p_dialinginfo.id[i] != 'T')
1932                                 goto dial_error;
1933                         SCAT(string, "ST");
1934                         SCCAT(dial, 'c');
1935                         dash = 1;
1936                         break;
1937                         default:
1938                         break;
1939                 }
1940                 /* stop, if ST */
1941                 if (dial[0] && dial[strlen(dial)-1] == 'c')
1942                         break;
1943         }
1944         /* terminate */
1945         if (dial[0] && dial[strlen(dial)-1]!='c') {
1946                 SCCAT(string, '-');
1947                 SCAT(string, "ST");
1948                 SCCAT(dial, 'c');
1949         }
1950
1951         /* error in dial string */
1952         if (!dial[0]) {
1953                 dial_error:
1954                 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_REQ, p_m_b_channel);
1955                 add_trace("string", NULL, "%s", p_dialinginfo.id);
1956                 if (!dial[0])
1957                         add_trace("error", NULL, "no number", dial);
1958                 else if (dial[0]!='a' && dial[0]!='b')
1959                         add_trace("error", NULL, "number must start with KP1/KP2", dial);
1960                 else
1961                         add_trace("error", NULL, "illegal format", dial);
1962                 end_trace();
1963                 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1964                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1965                 message->param.disconnectinfo.cause = CAUSE_INVALID;
1966                 message_put(message);
1967                 return;
1968         }
1969
1970         /* copy new dial string */
1971         SCPY(p_dialinginfo.id, dial);
1972
1973         /* attach only if not already */
1974         epointlist_new(epoint_id);
1975
1976         ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_REQ, p_m_b_channel);
1977         add_trace("string", NULL, "%s", string);
1978         add_trace("type", NULL, "%s", (dial[0]=='b')?"international":"national");
1979         add_trace("number", NULL, "%s", dial);
1980         end_trace();
1981         /* connect auto path */
1982         if ((p_m_mISDNport->ss5 & SS5_FEATURE_CONNECT)) {
1983                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
1984                 message_put(message);
1985         } else {
1986                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
1987                 message_put(message);
1988         }
1989
1990         /* start seizing */
1991         ss5_trace_header(p_m_mISDNport, this, SS5_SEIZING_REQ, p_m_b_channel);
1992         end_trace();
1993         new_ss5_state(SS5_STATE_SEIZING);
1994         new_ss5_signal(SS5_SIGNAL_SEND_ON);
1995         p_m_s_sample_nr = 0;
1996         inband_send_on();
1997
1998         p_type = PORT_TYPE_SS5_OUT;
1999         new_state(PORT_STATE_OUT_SETUP);
2000 }
2001
2002 /* MESSAGE_CONNECT */
2003 void Pss5::message_connect(unsigned int epoint_id, int message_id, union parameter *param)
2004 {
2005         memcpy(&p_connectinfo, &param->connectinfo, sizeof(p_connectinfo));
2006
2007         if (p_state != PORT_STATE_CONNECT) {
2008                 p_m_s_queued_signal = SS5_ANSWER_REQ;
2009                 new_state(PORT_STATE_CONNECT);
2010                 trigger_work(&p_m_s_queue);
2011         }
2012
2013         set_tone("", NULL);
2014 }
2015
2016 /* MESSAGE_DISCONNECT */
2017 void Pss5::message_disconnect(unsigned int epoint_id, int message_id, union parameter *param)
2018 {
2019         /* release and clear forward */
2020         if (p_type==PORT_TYPE_SS5_OUT) { /* outgoing exchange */
2021                 do_release(param->disconnectinfo.cause, param->disconnectinfo.location, SS5_CLEAR_FORWARD_REQ);
2022                 return;
2023         }
2024         /* release and clear back */
2025         if ((p_m_mISDNport->ss5 & SS5_FEATURE_RELEASE)) {
2026                 do_release(param->disconnectinfo.cause, param->disconnectinfo.location, SS5_CLEAR_BACK_REQ);
2027                 return;
2028         }
2029
2030         /* disconnect by sending clear back (after answer) or busy flash (before answer) */
2031         if (p_state != PORT_STATE_OUT_DISCONNECT) {
2032                 if (p_state == PORT_STATE_CONNECT)
2033                         p_m_s_queued_signal = SS5_CLEAR_BACK_REQ;
2034                 else
2035                         p_m_s_queued_signal = SS5_BUSY_FLASH_REQ;
2036                 new_state(PORT_STATE_OUT_DISCONNECT);
2037                 trigger_work(&p_m_s_queue);
2038         }
2039 }
2040
2041 /* MESSAGE_RELEASE */
2042 void Pss5::message_release(unsigned int epoint_id, int message_id, union parameter *param)
2043 {
2044         /* always send clear forward, because release guard only works as a reply to clear forward */
2045         do_release(param->disconnectinfo.cause, param->disconnectinfo.location, SS5_CLEAR_FORWARD_REQ);
2046 }
2047
2048 /*
2049  * endpoint sends messages to the port
2050  */
2051 int Pss5::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
2052 {
2053         if (PmISDN::message_epoint(epoint_id, message_id, param))
2054                 return(1);
2055
2056         switch(message_id) {
2057                 case MESSAGE_SETUP: /* dial-out command received from epoint */
2058                 if (p_state!=PORT_STATE_IDLE) {
2059                         PERROR("Pss5(%s) ignoring setup because isdn port is not in idle state (or connected for sending display info).\n", p_name);
2060                         break;
2061                 }
2062                 if (p_epointlist && p_state==PORT_STATE_IDLE)
2063                         FATAL("Pss5(%s): epoint pointer is set in idle state, how bad!!\n", p_name);
2064                 message_setup(epoint_id, message_id, param);
2065                 break;
2066
2067                 case MESSAGE_CONNECT: /* call of endpoint is connected */
2068                 message_connect(epoint_id, message_id, param);
2069                 break;
2070
2071                 case MESSAGE_DISCONNECT: /* call has been disconnected */
2072                 message_disconnect(epoint_id, message_id, param);
2073                 break;
2074
2075                 case MESSAGE_RELEASE: /* release isdn port */
2076                 message_release(epoint_id, message_id, param);
2077                 break;
2078
2079                 default:
2080                 PDEBUG(DEBUG_SS5, "Pss5(%s) ss5 port with (caller id %s) received an unhandled message: %d\n", p_name, p_callerinfo.id, message_id);
2081         }
2082
2083         return(1);
2084 }
2085