Add FXS support
[lcr.git] / apppbx.cpp
1 /*****************************************************************************\
2 **                                                                           **
3 ** Linux Call Router                                                         **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** The EndpointAppPBX implements PBX4Linux                                   **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12
13 #include "main.h"
14
15 class EndpointAppPBX *apppbx_first = NULL;
16
17 int action_timeout(struct lcr_timer *timer, void *instance, int index);
18 int match_timeout(struct lcr_timer *timer, void *instance, int index);
19 int redial_timeout(struct lcr_timer *timer, void *instance, int index);
20 int powerdial_timeout(struct lcr_timer *timer, void *instance, int index);
21 int cfnr_timeout(struct lcr_timer *timer, void *instance, int index);
22 int cfnr_call_timeout(struct lcr_timer *timer, void *instance, int index);
23 int password_timeout(struct lcr_timer *timer, void *instance, int index);
24 int callback_timeout(struct lcr_timer *timer, void *instance, int index);
25
26 /*
27  * EndpointAppPBX constructor
28  */
29 EndpointAppPBX::EndpointAppPBX(class Endpoint *epoint, int origin) : EndpointApp(epoint, origin, EAPP_TYPE_PBX)
30 {
31         class EndpointAppPBX **apppointer;
32
33 #ifdef WITH_CRYPT
34         memset(&e_crypt_handler, 0, sizeof(e_crypt_handler));
35         add_timer(&e_crypt_handler, crypt_handler, this, 0);
36 #endif
37         memset(&e_vbox_refresh, 0, sizeof(e_vbox_refresh));
38         add_timer(&e_vbox_refresh, vbox_refresh, this, 0);
39         memset(&e_action_timeout, 0, sizeof(e_action_timeout));
40         add_timer(&e_action_timeout, action_timeout, this, 0);
41         memset(&e_match_timeout, 0, sizeof(e_match_timeout));
42         add_timer(&e_match_timeout, match_timeout, this, 0);
43         memset(&e_redial_timeout, 0, sizeof(e_redial_timeout));
44         add_timer(&e_redial_timeout, redial_timeout, this, 0);
45         memset(&e_powerdial_timeout, 0, sizeof(e_powerdial_timeout));
46         add_timer(&e_powerdial_timeout, powerdial_timeout, this, 0);
47         memset(&e_cfnr_timeout, 0, sizeof(e_cfnr_timeout));
48         add_timer(&e_cfnr_timeout, cfnr_timeout, this, 0);
49         memset(&e_cfnr_call_timeout, 0, sizeof(e_cfnr_call_timeout));
50         add_timer(&e_cfnr_call_timeout, cfnr_call_timeout, this, 0);
51         memset(&e_callback_timeout, 0, sizeof(e_callback_timeout));
52         add_timer(&e_callback_timeout, callback_timeout, this, 0);
53         memset(&e_password_timeout, 0, sizeof(e_password_timeout));
54         add_timer(&e_password_timeout, password_timeout, this, 0);
55         e_powerdial_on = 0;
56
57         /* add application to chain */
58         next = NULL;
59         apppointer = &apppbx_first;
60         while(*apppointer)
61                 apppointer = &((*apppointer)->next);
62         *apppointer = this;
63
64         /* initialize */
65         memset(&e_ext, 0, sizeof(struct extension));
66         // *************** NOTE: also change value in read_extension() **************
67         e_ext.rights = 4; /* international */
68         e_ext.rx_gain = e_ext.tx_gain = 0;
69         e_state = EPOINT_STATE_IDLE;
70         e_ext.number[0] = '\0';
71         e_extension_interface[0] = '\0';
72         memset(&e_callerinfo, 0, sizeof(struct caller_info));
73         memset(&e_dialinginfo, 0, sizeof(struct dialing_info));
74         memset(&e_connectinfo, 0, sizeof(struct connect_info));
75         memset(&e_redirinfo, 0, sizeof(struct redir_info));
76         memset(&e_capainfo, 0, sizeof(struct capa_info));
77         memset(&e_rtpinfo, 0, sizeof(struct rtp_info));
78         e_start = e_stop = 0;
79         e_origin = origin;
80         e_ruleset = ruleset_main;
81         if (e_ruleset)
82                 e_rule = e_ruleset->rule_first;
83         e_rule_nesting = 0;
84         e_action = NULL;
85         e_match_to_action = NULL;
86         e_select = 0;
87         e_extdialing = e_dialinginfo.id;
88 //        e_knocking = 0;
89 //        e_knocktime = 0;
90         e_hold = 0;
91 //        e_join_tone[0] = e_hold_tone[0] = '\0';
92         e_join_pattern /*= e_hold_pattern*/ = 0;
93         e_tone[0] = '\0';
94         e_adminid = 0; // will be set, if call was initiated via admin socket
95         e_powerdelay = 0;
96         e_powerlimit = 0;
97         e_cbdialing[0] = '\0';
98         e_cbcaller[0] = '\0';
99         e_cbto[0] = '\0';
100         memset(&e_callbackinfo, 0, sizeof(struct caller_info));
101         e_connectedmode = 0;
102         e_dtmf = 0;
103         e_dtmf_time = 0;
104         e_dtmf_last = 0;
105         e_enablekeypad = 0;
106         e_multipoint_cause = 0;
107         e_multipoint_location = 0;
108         e_dialing_queue[0] = '\0';
109 #ifdef WITH_CRYPT
110         e_crypt = CRYPT_OFF;
111         e_crypt_state = CM_ST_NULL;
112         e_crypt_keyengine_busy = 0;
113         e_crypt_info[0] = '\0';
114 #endif
115         e_overlap = 0;
116         e_vbox[0] = '\0';
117         e_tx_state = NOTIFY_STATE_ACTIVE;
118         e_rx_state = NOTIFY_STATE_ACTIVE;
119         e_join_cause = e_join_location = 0;
120 /*********************************
121  *********************************
122  ********* ATTENTION *************
123  *********************************
124  *********************************/
125 /* if you add new values, that must be initialized, also check if they must
126  * be initialized when doing callback
127  */
128
129 }
130
131 /*
132  * EpointAppPBX destructor
133  */
134 EndpointAppPBX::~EndpointAppPBX(void)
135 {
136         class EndpointAppPBX *temp, **tempp;
137
138 #ifdef WITH_CRYPT
139         del_timer(&e_crypt_handler);
140 #endif
141         del_timer(&e_vbox_refresh);
142         del_timer(&e_action_timeout);
143         del_timer(&e_match_timeout);
144         del_timer(&e_redial_timeout);
145         del_timer(&e_powerdial_timeout);
146         del_timer(&e_cfnr_timeout);
147         del_timer(&e_cfnr_call_timeout);
148         del_timer(&e_callback_timeout);
149         del_timer(&e_password_timeout);
150
151         /* detach */
152         temp =apppbx_first;
153         tempp = &apppbx_first;
154         while(temp) {
155                 if (temp == this)
156                         break;
157
158                 tempp = &temp->next;
159                 temp = temp->next;
160         }
161         if (temp == 0)
162                 FATAL("Endpoint not in endpoint's list.\n");
163         *tempp = next;
164
165 }
166
167
168 /*
169  * trace header for application
170  */
171 void EndpointAppPBX::trace_header(const char *name, int direction)
172 {
173         struct trace _trace;
174
175         char msgtext[sizeof(_trace.name)];
176
177         SCPY(msgtext, name);
178
179         /* init trace with given values */
180         start_trace(-1,
181                     NULL,
182                     numberrize_callerinfo(e_callerinfo.id, e_callerinfo.ntype, options.national, options.international),
183                     e_dialinginfo.id,
184                     direction,
185                     CATEGORY_EP,
186                     ea_endpoint->ep_serial,
187                     msgtext);
188 }
189
190
191 EPOINT_STATE_NAMES
192
193 /* set new endpoint state
194  */
195 void EndpointAppPBX::new_state(int state)
196 {
197 #if 0
198         if (e_state != state) {
199                 trace_header("NEW STATE", DIRECTION_NONE);
200                 add_trace("state", "old", "%s", state_name[e_state]);
201                 add_trace("state", "new", "%s", state_name[state]);
202                 end_trace();
203         }
204 #endif
205         e_state = state;
206 }
207
208
209 /* release join and port (as specified)
210  */
211 void EndpointAppPBX::release(int release, int joinlocation, int joincause, int portlocation, int portcause, int force)
212 {
213         struct port_list *portlist;
214         struct lcr_msg *message;
215         char cause[16];
216
217         /* message to test call */
218         admin_call_response(e_adminid, ADMIN_CALL_RELEASE, "", joincause, joinlocation, 0);
219
220         /* if a release is pending */
221         if (release==RELEASE_JOIN || release==RELEASE_ALL || release==RELEASE_PORT_JOINONLY) {
222                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): do pending release (joincause %d location %d)\n", ea_endpoint->ep_serial, joincause, joinlocation);
223                 if (ea_endpoint->ep_join_id) {
224                         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_RELEASE);
225                         message->param.disconnectinfo.cause = joincause;
226                         message->param.disconnectinfo.location = joinlocation;
227                         message_put(message);
228                         ea_endpoint->ep_join_id = 0;
229                 }
230                 e_join_pattern = 0;
231 #if 0
232                 if (release != RELEASE_PORT_JOINONLY) {
233                         if (e_hold_id)
234                                 join_release(e_hold_id, ea_endpoint->ep_serial, 1, joinlocation, joincause);
235                         e_hold_id = 0;
236                 }
237 #endif
238         }
239         if (release==RELEASE_ALL || release==RELEASE_PORT_JOINONLY) {
240                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) do pending release (portcause %d portlocation)\n", ea_endpoint->ep_serial, portcause, portlocation);
241                 while((portlist = ea_endpoint->ep_portlist)) {
242                         if (portlist->port_id) {
243                                 SPRINT(cause, "cause_%02x", portcause);
244                                 set_tone(portlist, cause);
245                                 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_RELEASE);
246                                 message->param.disconnectinfo.cause = portcause;
247                                 message->param.disconnectinfo.location = portlocation;
248                                 message->param.disconnectinfo.force = force; // set, if port should release imediately
249                                 message_put(message);
250                                 logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
251                         }
252                         ea_endpoint->free_portlist(portlist);
253                 }
254
255                 /* if callback is enabled, call back with the given caller id */
256                 if (e_callback_timeout.active) {
257                         /* reset some stuff */
258                         new_state(EPOINT_STATE_IDLE);
259                         memset(&e_connectinfo, 0, sizeof(struct connect_info));
260                         memset(&e_redirinfo, 0, sizeof(struct redir_info));
261                         e_start = e_stop = 0;
262                         e_ruleset = ruleset_main;
263                         if (e_ruleset)
264                                 e_rule = e_ruleset->rule_first;
265                         e_action = NULL;
266                         unsched_timer(&e_action_timeout);
267                         unsched_timer(&e_match_timeout);
268                         unsched_timer(&e_cfnr_timeout);
269                         unsched_timer(&e_cfnr_call_timeout);
270                         e_match_to_action = NULL;
271                         //e_select = 0;
272                         e_extdialing = e_dialinginfo.id;
273                         e_connectedmode = 0;
274                         e_dtmf = 0;
275                         e_dtmf_time = 0;
276                         e_dtmf_last = 0;
277                         e_enablekeypad = 0;
278                         e_multipoint_cause = 0;
279                         e_multipoint_location = 0;
280                         e_dialing_queue[0] = '\0';
281 #ifdef WITH_CRYPT
282                         e_crypt = 0;
283                         e_crypt_state = CM_ST_NULL;
284                         e_crypt_keyengine_busy = 0;
285                         e_crypt_info[0] = '\0'; 
286 #endif
287                         e_tone[0] = '\0';
288                         e_overlap = 0;
289                         e_vbox[0] = '\0';
290                         e_tx_state = NOTIFY_STATE_ACTIVE;
291                         e_rx_state = NOTIFY_STATE_ACTIVE;
292                         e_join_cause = e_join_location = 0;
293                         e_rule_nesting = 0;
294                         /* the caller info of the callback user */
295                         memcpy(&e_callbackinfo, &e_callerinfo, sizeof(e_callbackinfo));
296                         memset(&e_dialinginfo, 0, sizeof(e_dialinginfo));
297                         /* create dialing by callerinfo */
298                         if (e_ext.number[0] && e_extension_interface[0]) {
299                                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) preparing callback to internal: %s interface %s\n", ea_endpoint->ep_serial, e_ext.number, e_extension_interface);
300                                 /* create callback to the current terminal */
301                                 SCPY(e_dialinginfo.id, e_ext.number);
302                                 SCPY(e_dialinginfo.interfaces, e_extension_interface);
303                                 e_dialinginfo.itype = INFO_ITYPE_ISDN_EXTENSION;
304                                 e_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
305                         } else {
306                                 if (e_cbto[0]) {
307                                         SCPY(e_dialinginfo.id, e_cbto);
308                                 } else {
309                                         /* numberrize caller id and use it to dial to the callback */
310                                         SCPY(e_dialinginfo.id, numberrize_callerinfo(e_callerinfo.id,e_callerinfo.ntype, options.national, options.international));
311                                 }
312                                 e_dialinginfo.itype = INFO_ITYPE_ISDN;
313                                 e_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
314                                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) preparing callback to external: %s\n", ea_endpoint->ep_serial, e_dialinginfo.id);
315                         }
316                         return;
317                 }
318
319                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) do pending release of epoint itself.\n", ea_endpoint->ep_serial);
320                 if (--ea_endpoint->ep_use <= 0) /* when e_lock is 0, the endpoint will be deleted */
321                         trigger_work(&ea_endpoint->ep_delete);
322                 return;
323         }
324 }
325
326
327 /* cancel callerid if restricted, unless anon-ignore is enabled at extension or port is of type external (so called police gets caller id :)*/
328 void apply_callerid_restriction(struct extension *ext, char *id, int *ntype, int *present, int *screen, char *extension, char *name)
329 {
330         PDEBUG(DEBUG_EPOINT, "id='%s' ntype=%d present=%d screen=%d extension='%s' name='%s'\n", (id)?id:"NULL", (ntype)?*ntype:-1, (present)?*present:-1, (screen)?*screen:-1, (extension)?extension:"NULL", (name)?name:"NULL");
331
332         /* caller id is not restricted, so we do nothing */
333         if (*present != INFO_PRESENT_RESTRICTED)
334                 return;
335
336         /* only extensions are restricted */
337         if (!ext->number[0])
338                 return;
339
340         /* if we enabled anonymouse ignore */
341         if (ext->anon_ignore)
342                 return;
343
344         /* else we remove the caller id */
345         if (id)
346                 id[0] = '\0';
347         if (ntype)
348                 *ntype = INFO_NTYPE_UNKNOWN;
349 //      if (screen)
350 //              *screen = INFO_SCREEN_USER;
351 // maybe we should not make voip address anonymous
352 //      if (voip)
353 //              voip[0] = '\0';
354 // maybe it's no fraud to present extension id
355 //      if (extension)
356 //              extension[0] = '\0';
357         if (name)
358                 name[0] = '\0';
359 }
360
361 /* used display message to display callerid as available */
362 char *EndpointAppPBX::apply_callerid_display(const char *id, int itype, int ntype, int present, int screen, const char *extension, const char *name)
363 {
364         static char display[81];
365
366         display[0] = '\0';
367         const char *cid = numberrize_callerinfo(id, ntype, options.national, options.international);
368
369         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) id='%s' itype=%d ntype=%d present=%d screen=%d extension='%s' name='%s'\n", ea_endpoint->ep_serial, (id)?id:"NULL", itype, ntype, present, screen, (extension)?extension:"NULL", (name)?name:"NULL");
370
371         if (!id)
372                 id = "";
373         if (!extension)
374                 extension = "";
375         if (!name)
376                 name = "";
377
378         /* NOTE: is caller is is not available for this extesion, it has been removed by apply_callerid_restriction already */
379
380         /* internal extension's caller id */
381         if (extension[0] && e_ext.display_int) {
382                 if (!display[0])
383                         SCAT(display, extension);
384                 if (display[0])
385                         SCAT(display, " ");
386                 if (itype == INFO_ITYPE_VBOX)
387                         SCAT(display, "(vbox)");
388                 else
389                         SCAT(display, "(int)");
390         }
391
392         /* external caller id */
393         if (!extension[0] && e_ext.display_ext) {
394                 if (!display[0]) {
395                         if (!cid[0]) {
396                                 if (present == INFO_PRESENT_RESTRICTED)
397                                         SCAT(display, "anonymous");
398                                 else
399                                         SCAT(display, "unknown");
400                         }
401                         else
402                                 SCAT(display, cid);
403                 }
404         }
405
406         /* display if callerid is anonymouse but available due anon-ignore */
407         if (e_ext.display_anon && present==INFO_PRESENT_RESTRICTED) {
408                 if (!cid[0])
409                         SCAT(display, "unknown");
410                 else 
411                         SCAT(display, cid);
412                 SCAT(display, " anon");
413         }
414
415         /* display if callerid is anonymouse but available due anon-ignore */
416         if (e_ext.display_fake && screen==INFO_SCREEN_USER && ntype!=INFO_NTYPE_NOTPRESENT) {
417                 if (!display[0]) {
418                         if (!id[0]) {
419                                 if (present == INFO_PRESENT_RESTRICTED)
420                                         SCAT(display, "anonymous");
421                                 else
422                                         SCAT(display, "unknown");
423                         }
424                         else
425                                 SCAT(display, cid);
426                 }
427                 SCAT(display, " fake");
428         }
429
430         /* caller name */
431         if (name[0] && e_ext.display_name) {
432                 if (!display[0] && cid[0])
433                                 SCAT(display, cid);
434                 if (display[0])
435                                 SCAT(display, " ");
436                 SCAT(display, name);
437         }
438
439         return(display);
440 }
441
442 /*
443  * uses the current state to notify activity
444  */
445 void EndpointAppPBX::notify_active(void)
446 {
447         struct port_list *portlist = ea_endpoint->ep_portlist;
448         struct lcr_msg *message;
449         int notify = 0;
450
451         switch(e_tx_state) {
452                 case NOTIFY_STATE_ACTIVE:
453                 /* we are already active, so we don't do anything */
454                 break;
455
456                 case NOTIFY_STATE_SUSPEND:
457                 notify = INFO_NOTIFY_USER_RESUMED;
458                 while(portlist) {
459                         set_tone(portlist, NULL);
460                         portlist = portlist->next;
461                 }
462                 portlist = ea_endpoint->ep_portlist;
463                 break;
464
465                 case NOTIFY_STATE_HOLD:
466                 notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
467                 while(portlist) {
468                         set_tone(portlist, NULL);
469                         portlist = portlist->next;
470                 }
471                 portlist = ea_endpoint->ep_portlist;
472                 break;
473
474                 case NOTIFY_STATE_CONFERENCE:
475                 notify = INFO_NOTIFY_CONFERENCE_DISCONNECTED;
476                 while(portlist) {
477                         set_tone(portlist, NULL);
478                         portlist = portlist->next;
479                 }
480                 portlist = ea_endpoint->ep_portlist;
481                 break;
482
483                 default:
484                 PERROR("unknown e_tx_state = %d\n", e_tx_state);
485         }
486
487         if (notify)
488         while(portlist) {
489                 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
490                 message->param.notifyinfo.notify = notify;
491                 message_put(message);
492                 logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
493                 portlist = portlist->next;
494         }
495 }
496
497
498 /*
499  * keypad functions during call. one example to use this is to put a call on hold or start a conference
500  */
501 void EndpointAppPBX::keypad_function(char digit)
502 {
503         class Port *port;
504
505         /* we must be in a call, in order to send messages to the call */
506         if (e_ext.number[0] == '\0') {
507                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) IGNORING keypad received not from extension.\n", ea_endpoint->ep_serial);
508                 return;
509         }
510
511         switch(digit) {
512                 /* join conference */
513                 case '3':
514                 if (ea_endpoint->ep_join_id == 0) {
515                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) keypad received during connect but not during a call.\n", ea_endpoint->ep_serial);
516                         break;
517                 }
518                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) join call with call on hold\n", ea_endpoint->ep_serial);
519                 port = find_port_id(ea_endpoint->ep_portlist->port_id);
520                 if (!port)
521                         break;
522                 if ((port->p_type & PORT_CLASS_POTS_MASK) == PORT_CLASS_POTS_FXS)
523                         join_join_fxs();
524                 else if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_DSS1)
525                         join_join_dss1();
526                 break;
527
528 #ifdef WITH_CRYPT
529                 /* crypt shared */
530                 case '7':
531                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) shared key encryption selected.\n", ea_endpoint->ep_serial);
532                 encrypt_shared();
533                 break;
534
535                 /* crypt key-exchange */
536                 case '8':
537                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) key exchange encryption selected.\n", ea_endpoint->ep_serial);
538                 encrypt_keyex();
539                 break;
540
541                 /* crypt off */
542                 case '9':
543                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption off selected.\n", ea_endpoint->ep_serial);
544                 encrypt_off();
545                 break;
546 #endif
547
548                 default:        
549                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) unsupported keypad digit '%c'.\n", ea_endpoint->ep_serial, digit);
550         }
551 }
552
553
554 /* set tone pattern for port */
555 void EndpointAppPBX::set_tone(struct port_list *portlist, const char *tone)
556 {
557         struct lcr_msg *message;
558
559         if (!tone)
560                 tone = "";
561
562         /* store for suspended processes */
563         SCPY(e_tone, tone);
564
565
566         if (e_join_pattern /* pattern are provided */
567          && !(e_ext.own_setup && e_state == EPOINT_STATE_IN_SETUP)
568          && !(e_ext.own_setup && e_state == EPOINT_STATE_IN_OVERLAP)
569          && !(e_ext.own_proceeding && e_state == EPOINT_STATE_IN_PROCEEDING)
570          && !(e_ext.own_alerting && e_state == EPOINT_STATE_IN_ALERTING)
571          && !(e_ext.own_cause && e_state == EPOINT_STATE_IN_DISCONNECT)
572          && !(e_ext.own_setup && e_state == EPOINT_STATE_OUT_SETUP)
573          && !(e_ext.own_setup && e_state == EPOINT_STATE_OUT_OVERLAP)
574          && !(e_ext.own_proceeding && e_state == EPOINT_STATE_OUT_PROCEEDING)
575          && !(e_ext.own_alerting && e_state == EPOINT_STATE_OUT_ALERTING)
576          && !(e_ext.own_cause && e_state == EPOINT_STATE_OUT_DISCONNECT)
577          && tone[0] && !!strncmp(tone,"crypt_*",6)) {
578                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) tone not provided since patterns are available\n", ea_endpoint->ep_serial);
579                 tone = "";
580         }
581
582         if (portlist) {
583                 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_TONE);
584                 SCPY(message->param.tone.dir, e_ext.tones_dir);
585                 SCPY(message->param.tone.name, tone);
586                 message_put(message);
587                 logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
588         } else {
589                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) no port to notify tone.\n", ea_endpoint->ep_serial);
590                 return;
591         }
592 }
593
594
595 /* outgoing setup to port(s)
596  * ports will be created and a setup is sent if everything is ok. otherwhise
597  * the endpoint is destroyed.
598  */
599 void EndpointAppPBX::out_setup(int cfnr)
600 {
601         struct dialing_info     dialinginfo;
602         class Port              *port;
603         struct port_list        *portlist;
604         struct lcr_msg          *message;
605         int                     anycall = 0;
606         int                     cause = CAUSE_RESSOURCEUNAVAIL;
607         const char              *p;
608         char                    cfp[64];
609         struct interface        *interface;
610 #ifdef WITH_MISDN
611         struct mISDNport        *mISDNport;
612 #endif
613         char                    portname[32];
614         char                    *dirname;
615         class EndpointAppPBX    *atemp;
616 //      char                    allowed_ports[256];
617 //      char                    exten[256];
618         char                    ifname[sizeof(e_ext.interfaces)],
619                                 *ifname_p,
620                                 number[256],
621                                 *number_p;
622         struct port_settings    port_settings;
623 #ifdef WITH_MISDN
624         int                     channel = 0;
625 #endif
626         struct admin_list       *admin;
627         int                     earlyb;
628         int                     mode = B_MODE_TRANSPARENT;
629
630         /* set bchannel mode */
631         mode = e_capainfo.source_mode;
632
633         /* create settings for creating port */
634         memset(&port_settings, 0, sizeof(port_settings));
635         if (e_ext.tones_dir)
636                 SCPY(port_settings.tones_dir, e_ext.tones_dir);
637         else
638                 SCPY(port_settings.tones_dir, options.tones_dir);
639         port_settings.no_seconds = e_ext.no_seconds;
640         
641         /* NOTE: currently the try_card feature is not supported. it should be used later to try another card, if the outgoing call fails on one port */
642
643         /* check what dialinginfo.itype we got */
644         switch(e_dialinginfo.itype) {
645                 /* *********************** call to extension or vbox */
646                 case INFO_ITYPE_ISDN_EXTENSION:
647                 /* check if we deny incoming calls when we use an extension */
648                 if (e_ext.noknocking) {
649                         atemp = apppbx_first;
650                         while(atemp) {
651                                 if (atemp != this)
652                                 if (!strcmp(atemp->e_ext.number, e_ext.number))
653                                         break;
654                                 atemp = atemp->next;
655                         }
656                         if (atemp) {
657                                 PERROR("EPOINT(%d) noknocking and currently a call\n", ea_endpoint->ep_serial);
658                                 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_BUSY, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYSPE_ join, port */
659                                 return; /* must exit here */
660                         }
661                 }
662                 /* FALL THROUGH !!!! */
663                 case INFO_ITYPE_VBOX:
664                 /* get dialed extension's info */
665 //              SCPY(exten, e_dialinginfo.id);
666 //              if (strchr(exten, ','))
667 //                      *strchr(exten, ',') = '\0';
668 //              if (!read_extension(&e_ext, exten))
669                 if (!read_extension(&e_ext, e_dialinginfo.id)) {
670                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) extension %s not configured\n", ea_endpoint->ep_serial, e_dialinginfo.id);
671                         release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_OUTOFORDER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYPE, join, port */
672                         return; /* must exit here */
673                 }
674                 e_dialinginfo.sending_complete = 1;
675
676                 if (e_dialinginfo.itype == INFO_ITYPE_VBOX) {
677                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing directly to VBOX\n", ea_endpoint->ep_serial);
678                         p = "vbox";
679                         goto vbox_only;
680                 }
681
682                 /* string from unconditional call forward (cfu) */
683                 p = e_ext.cfu;
684                 if (*p) {
685                         /* present to forwarded party */
686                         if (e_ext.anon_ignore && e_callerinfo.id[0]) {
687                                 e_callerinfo.present = INFO_PRESENT_ALLOWED;
688                         }
689                         if (!!strcmp(p, "vbox") || (e_capainfo.bearer_capa==INFO_BC_AUDIO) || (e_capainfo.bearer_capa==INFO_BC_SPEECH))
690                                 goto cfu_only;
691                 }
692
693                 /* string from busy call forward (cfb) */
694                 p = e_ext.cfb;
695                 if (*p) {
696                         class EndpointAppPBX *checkapp = apppbx_first;
697                         while(checkapp) {
698                                 if (checkapp != this) { /* any other endpoint except our own */
699                                         if (!strcmp(checkapp->e_ext.number, e_ext.number)) {
700                                                 /* present to forwarded party */
701                                                 if (e_ext.anon_ignore && e_callerinfo.id[0]) {
702                                                         e_callerinfo.present = INFO_PRESENT_ALLOWED;
703                                                 }
704                                                 if (!!strcmp(p, "vbox") || (e_capainfo.bearer_capa==INFO_BC_AUDIO) || (e_capainfo.bearer_capa==INFO_BC_SPEECH))
705                                                         goto cfb_only;
706                                         }
707                                 }
708                                 checkapp = checkapp->next;
709                         }
710                 }
711
712                 /* string from no-response call forward (cfnr) */
713                 p = e_ext.cfnr;
714                 if (*p) {
715                         /* when cfnr is done, out_setup() will setup the call */
716                         if (cfnr) {
717                                 /* present to forwarded party */
718                                 if (e_ext.anon_ignore && e_callerinfo.id[0]) {
719                                         e_callerinfo.present = INFO_PRESENT_ALLOWED;
720                                 }
721                                 goto cfnr_only;
722                         }
723                         if (!!strcmp(p, "vbox") || (e_capainfo.bearer_capa==INFO_BC_AUDIO) || (e_capainfo.bearer_capa==INFO_BC_SPEECH)) {
724                                 schedule_timer(&e_cfnr_timeout, e_ext.cfnr_delay, 0);
725                                 schedule_timer(&e_cfnr_call_timeout, e_ext.cfnr_delay + 1, 0); /* call one second after release */
726                                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) setting time for call-forward-busy to %s with delay %ld.\n", ea_endpoint->ep_serial, e_ext.cfnr, e_ext.cfnr_delay);
727                         }
728                 }
729
730                 /* call to all internal interfaces */
731                 p = e_ext.interfaces;
732                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) generating multiple joins for extension %s to interfaces %s\n", ea_endpoint->ep_serial, e_dialinginfo.id, p);
733                 while(*p) {
734                         earlyb = 0;
735                         ifname[0] = '\0';
736                         while(*p!=',' && *p!='\0')
737                                 if (*p > ' ')
738                                         SCCAT(ifname, *p++);
739                         if (*p == ',')
740                                 p++;
741                         /* search interface */
742                         interface = hunt_interface(ifname);
743                         if (!interface) {
744                                 trace_header("INTERFACE (not found)", DIRECTION_NONE);
745                                 add_trace("interface", NULL, "%s", ifname);
746                                 end_trace();
747                                 continue;
748                         }
749                         /* found interface */
750                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) calling to interface %s\n", ea_endpoint->ep_serial, ifname);
751                         if (interface->remote) {
752                                 admin = admin_first;
753                                 while(admin) {
754                                         if (admin->remote_name[0] && !strcmp(admin->remote_name, interface->remote_app))
755                                                 break;
756                                         admin = admin->next;
757                                 }
758                                 if (!admin) {
759                                         trace_header("INTERFACE (remote not connected)", DIRECTION_NONE);
760                                         add_trace("application", NULL, "%s", interface->remote_app);
761                                         end_trace();
762                                         continue;
763                                 }
764                                 SPRINT(portname, "%s-%d-out", interface->name, 0);
765                                 port = new Premote(PORT_TYPE_REMOTE_OUT, portname, &port_settings, interface, admin->sock);
766                                 earlyb = (interface->is_earlyb == IS_YES);
767                         } else
768 #ifdef WITH_GSM_BS
769                         if (interface->gsm_bs) {
770                                 SPRINT(portname, "%s-%d-out", interface->name, 0);
771                                 port = new Pgsm_bs(PORT_TYPE_GSM_BS_OUT, portname, &port_settings, interface);
772                                 earlyb = (interface->is_earlyb == IS_YES);
773                         } else
774 #endif
775 #ifdef WITH_GSM_MS
776                         if (interface->gsm_ms) {
777                                 SPRINT(portname, "%s-%d-out", interface->name, 0);
778                                 port = new Pgsm_ms(PORT_TYPE_GSM_MS_OUT, portname, &port_settings, interface);
779                                 earlyb = (interface->is_earlyb == IS_YES);
780                         } else
781 #endif
782 #ifdef WITH_SIP
783                         if (interface->sip) {
784                                 SPRINT(portname, "%s-%d-out", interface->name, 0);
785                                 port = new Psip(PORT_TYPE_SIP_OUT, portname, &port_settings, interface);
786                                 earlyb = (interface->is_earlyb == IS_YES);
787                         } else
788 #endif
789                         {
790 #ifdef WITH_MISDN
791                                 /* hunt for mISDNport and create Port */
792                                 mISDNport = hunt_port(ifname, &channel);
793                                 if (!mISDNport) {
794                                         trace_header("INTERFACE (busy)", DIRECTION_NONE);
795                                         add_trace("interface", NULL, "%s", ifname);
796                                         end_trace();
797                                         continue;
798                                 }
799
800                                 SPRINT(portname, "%s-%d-out", mISDNport->ifport->interface->name, mISDNport->portnum);
801 #ifdef WITH_SS5
802                                 if (mISDNport->ss5)
803                                         port = ss5_hunt_line(mISDNport);
804                                 else
805 #endif
806 #ifdef ISDN_P_FXS_POTS
807                                 if (mISDNport->pots)
808                                         port = new Pfxs(PORT_TYPE_POTS_FXS_OUT, mISDNport, portname, &port_settings, mISDNport->ifport->interface, mode);
809                                 else
810 #endif
811                                         port = new Pdss1((mISDNport->ntmode)?PORT_TYPE_DSS1_NT_OUT:PORT_TYPE_DSS1_TE_OUT, mISDNport, portname, &port_settings, mISDNport->ifport->interface, channel, mISDNport->ifport->channel_force, mode);
812                                 earlyb = mISDNport->earlyb;
813 #else
814                         trace_header("INTERFACE (has no function)", DIRECTION_NONE);
815                         add_trace("interface", NULL, "%s", ifname);
816                         end_trace();
817                         continue;
818 #endif
819                         }
820                         if (!port)
821                                 FATAL("Failed to create Port instance\n");
822                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) got port %s\n", ea_endpoint->ep_serial, port->p_name);
823                         memset(&dialinginfo, 0, sizeof(dialinginfo));
824                         SCPY(dialinginfo.id, e_dialinginfo.id);
825                         dialinginfo.itype = INFO_ITYPE_ISDN_EXTENSION;
826                         dialinginfo.ntype = e_dialinginfo.ntype;
827                         /* create port_list relation */
828                         portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, earlyb);
829                         if (!portlist) {
830                                 PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
831                                 delete port;
832                                 goto check_anycall_intern;
833                         }
834                         /* directory.list */
835                         if (e_callerinfo.id[0] && e_ext.display_name) {
836                                 dirname = parse_directory(e_callerinfo.id, e_callerinfo.ntype);
837                                 if (dirname)
838                                         SCPY(e_callerinfo.name, dirname);
839                         }
840 //                      dss1 = (class Pdss1 *)port;
841                         /* message */
842 //printf("INTERNAL caller=%s,id=%s,dial=%s\n", param.setup.networkid, param.setup.callerinfo.id, param.setup.dialinginfo.id);
843                         message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_SETUP);
844                         memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
845                         memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
846                         memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
847                         memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
848                         memcpy(&message->param.setup.rtpinfo, &e_rtpinfo, sizeof(struct rtp_info));
849 //terminal                      SCPY(message->param.setup.from_terminal, e_ext.number);
850 //terminal                      if (e_dialinginfo.id)
851 //terminal                              SCPY(message->param.setup.to_terminal, e_dialinginfo.id);
852                         /* handle restricted caller ids */
853                         apply_callerid_restriction(&e_ext, message->param.setup.callerinfo.id, &message->param.setup.callerinfo.ntype, &message->param.setup.callerinfo.present, &message->param.setup.callerinfo.screen, message->param.setup.callerinfo.extension, message->param.setup.callerinfo.name);
854                         apply_callerid_restriction(&e_ext, message->param.setup.callerinfo.id2, &message->param.setup.callerinfo.ntype2, &message->param.setup.callerinfo.present2, &message->param.setup.callerinfo.screen2, message->param.setup.callerinfo.extension, message->param.setup.callerinfo.name);
855                         apply_callerid_restriction(&e_ext, message->param.setup.redirinfo.id, &message->param.setup.redirinfo.ntype, &message->param.setup.redirinfo.present, 0, message->param.setup.redirinfo.extension, NULL);
856                         /* display callerid if desired for extension */
857                         SCPY(message->param.setup.callerinfo.display, apply_callerid_display(message->param.setup.callerinfo.id, message->param.setup.callerinfo.itype, message->param.setup.callerinfo.ntype, message->param.setup.callerinfo.present, message->param.setup.callerinfo.screen, message->param.setup.callerinfo.extension, message->param.setup.callerinfo.name));
858 //printf("\n\ndisplay = %s\n\n\n",message->param.setup.callerinfo.display);
859                         /* use cnip, if enabld */
860         //              if (!e_ext.centrex)
861         //                      message->param.setup.callerinfo.name[0] = '\0';
862                         /* screen clip if prefix is required */
863                         if (message->param.setup.callerinfo.id[0] && e_ext.clip_prefix[0]) {
864                                 SCPY(message->param.setup.callerinfo.id, e_ext.clip_prefix);
865                                 SCAT(message->param.setup.callerinfo.id, numberrize_callerinfo(e_callerinfo.id,e_callerinfo.ntype, options.national, options.international));
866                                 message->param.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
867                         }
868                         if (message->param.setup.callerinfo.id2[0] && e_ext.clip_prefix[0]) {
869                                 SCPY(message->param.setup.callerinfo.id2, e_ext.clip_prefix);
870                                 SCAT(message->param.setup.callerinfo.id2, numberrize_callerinfo(e_callerinfo.id2,e_callerinfo.ntype2, options.national, options.international));
871                                 message->param.setup.callerinfo.ntype2 = INFO_NTYPE_UNKNOWN;
872                         }
873                         /* use internal caller id */
874                         if (e_callerinfo.extension[0] && (message->param.setup.callerinfo.present!=INFO_PRESENT_RESTRICTED || e_ext.anon_ignore)) {
875                                 SCPY(message->param.setup.callerinfo.id, e_callerinfo.extension);
876                                 message->param.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
877                                 message->param.setup.callerinfo.ntype2 = INFO_NTYPE_NOTPRESENT;
878                         }
879                         message_put(message);
880                         logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
881                         anycall = 1;
882                 }
883
884                 /* string from parallel call forward (cfp) */
885                 p = e_ext.cfp;
886                 if (*p) {
887                         if (e_ext.anon_ignore && e_callerinfo.id[0]) {
888                                 e_callerinfo.present = INFO_PRESENT_ALLOWED;
889                                 e_callerinfo.present2 = INFO_PRESENT_ALLOWED;
890                         }
891                 }
892
893                 vbox_only: /* entry point for answering machine only */
894                 cfu_only: /* entry point for cfu */
895                 cfb_only: /* entry point for cfb */
896                 cfnr_only: /* entry point for cfnr */
897                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call extension %s for external destiantion(s) '%s'\n", ea_endpoint->ep_serial, e_dialinginfo.id, p);
898 //              i=0;
899                 while(*p) {
900                         earlyb = 0;
901                         /* only if vbox should be dialed, and terminal is given */
902                         if (!strcmp(p, "vbox") && e_ext.number[0]) {
903                                 /* go to the end of p */
904                                 p += strlen(p);
905
906                                 /* answering vbox call */
907                                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) answering machine\n", ea_endpoint->ep_serial);
908                                 /* alloc port */
909                                 if (!(port = new VBoxPort(PORT_TYPE_VBOX_OUT, &port_settings)))
910                                         FATAL("No memory for VBOX Port instance\n");
911                                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) allocated port %s\n", ea_endpoint->ep_serial, port->p_name);
912                                 UCPY(cfp, e_ext.number); /* cfp or any other direct forward/vbox */
913                         } else {
914                                 cfp[0] = '\0';
915                                 while(*p!=',' && *p!='\0')
916                                         SCCAT(cfp, *p++);
917                                 if (*p == ',')
918                                         p++;
919                                 /* external call */
920                                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cfp external %s\n", ea_endpoint->ep_serial, cfp);
921 #ifdef WITH_MISDN
922                                 /* hunt for mISDNport and create Port */
923                                 mISDNport = hunt_port(e_dialinginfo.interfaces[0]?e_dialinginfo.interfaces:NULL, &channel);
924                                 if (mISDNport) {
925                                         /* creating EXTERNAL port*/
926                                         SPRINT(portname, "%s-%d-out", mISDNport->ifport->interface->name, mISDNport->portnum);
927 #ifdef WITH_SS5
928                                         if (mISDNport->ss5)
929                                                 port = ss5_hunt_line(mISDNport);
930                                         else
931 #endif
932 #ifdef ISDN_P_FXS_POTS
933                                         if (mISDNport->pots)
934                                                 port = new Pfxs(PORT_TYPE_POTS_FXS_OUT, mISDNport, portname, &port_settings, mISDNport->ifport->interface, mode);
935                                         else
936 #endif
937                                                 port = new Pdss1((mISDNport->ntmode)?PORT_TYPE_DSS1_NT_OUT:PORT_TYPE_DSS1_TE_OUT, mISDNport, portname, &port_settings, mISDNport->ifport->interface, channel, mISDNport->ifport->channel_force, mode);
938                                         if (!port)
939                                                 FATAL("No memory for Port instance\n");
940                                         earlyb = mISDNport->earlyb;
941                                 } else
942 #endif
943                                 {
944                                         port = NULL;
945                                         trace_header("INTERFACE (too busy)", DIRECTION_NONE);
946                                         add_trace("interface", NULL, "%s", e_dialinginfo.interfaces[0]?e_dialinginfo.interfaces:"any interface");
947                                         end_trace();
948                                 }
949                         }
950                         if (!port) {
951                                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) no port found or created, which is idle.\n", ea_endpoint->ep_serial);
952                                 goto check_anycall_intern;
953                         }
954                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) found or created port %s\n", ea_endpoint->ep_serial, port->p_name);
955                         memset(&dialinginfo, 0, sizeof(dialinginfo));
956                         SCPY(dialinginfo.id, cfp);
957                         dialinginfo.itype = INFO_ITYPE_ISDN;
958                         dialinginfo.ntype = e_dialinginfo.ntype;
959                         portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, earlyb);
960                         if (!portlist) {
961                                 PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
962                                 delete port;
963                                 goto check_anycall_intern;
964                         }
965 //printf("EXTERNAL caller=%s,id=%s,dial=%s\n", param.setup.networkid, param.setup.callerinfo.id, param.setup.dialinginfo.id);
966                         message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_SETUP);
967                         memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
968                         memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
969                         memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
970                         /* if clip is hidden */
971                         if (e_ext.clip==CLIP_HIDE && port->p_type!=PORT_TYPE_VBOX_OUT) {
972                                 SCPY(message->param.setup.callerinfo.id, e_ext.callerid);
973                                 SCPY(message->param.setup.callerinfo.extension, e_ext.number);
974                                 message->param.setup.callerinfo.ntype = e_ext.callerid_type;
975                                 message->param.setup.callerinfo.present = e_ext.callerid_present;
976                                 message->param.setup.callerinfo.ntype = INFO_NTYPE_NOTPRESENT;
977                         }
978                         memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
979 //terminal                      SCPY(message->param.setup.from_terminal, e_ext.number);
980 //terminal                      if (e_dialinginfo.id)
981 //terminal                              SCPY(message->param.setup.to_terminal, e_dialinginfo.id);
982                                 /* handle restricted caller ids */
983                         apply_callerid_restriction(&e_ext, message->param.setup.callerinfo.id, &message->param.setup.callerinfo.ntype, &message->param.setup.callerinfo.present, &message->param.setup.callerinfo.screen, message->param.setup.callerinfo.extension, message->param.setup.callerinfo.name);
984                         apply_callerid_restriction(&e_ext, message->param.setup.callerinfo.id2, &message->param.setup.callerinfo.ntype2, &message->param.setup.callerinfo.present2, &message->param.setup.callerinfo.screen2, message->param.setup.callerinfo.extension, message->param.setup.callerinfo.name);
985                         apply_callerid_restriction(&e_ext, message->param.setup.redirinfo.id, &message->param.setup.redirinfo.ntype, &message->param.setup.redirinfo.present, 0, message->param.setup.redirinfo.extension, NULL);
986                         /* display callerid if desired for extension */
987                         SCPY(message->param.setup.callerinfo.display, apply_callerid_display(message->param.setup.callerinfo.id, message->param.setup.callerinfo.itype, message->param.setup.callerinfo.ntype, message->param.setup.callerinfo.present, message->param.setup.callerinfo.screen, message->param.setup.callerinfo.extension, message->param.setup.callerinfo.name));
988                         message_put(message);
989                         logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
990                         anycall = 1;
991                 }
992
993                 check_anycall_intern:
994                 /* now we have all ports created */
995                 if (!anycall) {
996                         trace_header("INTERFACE (no extension's interface)", DIRECTION_NONE);
997                         end_trace();
998                         if (!ea_endpoint->ep_join_id)
999                                 break;
1000                         release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYPE, join, port */
1001                         return; /* must exit here */
1002                 }
1003                 break;
1004
1005                 /* *********************** external call */
1006                 default:
1007                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing external: called='%s' keypad='%s'\n", ea_endpoint->ep_serial, e_dialinginfo.id, e_dialinginfo.keypad);
1008                 /* call to extenal interfaces */
1009                 if (e_dialinginfo.keypad[0])
1010                         number_p = e_dialinginfo.keypad;
1011                 else
1012                         number_p = e_dialinginfo.id;
1013                 do {
1014                         number[0] = '\0';
1015                         while(*number_p!=',' && *number_p!='\0')
1016                                 SCCAT(number, *number_p++);
1017                         if (*number_p == ',')
1018                                 number_p++;
1019                         /* found number */
1020
1021                         ifname_p = e_dialinginfo.interfaces;
1022                         if (*ifname_p == '+')
1023                                 ifname_p++;
1024                         do {
1025                                 earlyb = 0;
1026                                 ifname[0] = '\0';
1027                                 while(*ifname_p!=',' && *ifname_p!='\0')
1028                                         SCCAT(ifname, *ifname_p++);
1029                                 if (*ifname_p == ',')
1030                                         ifname_p++;
1031                                 /* found interface name */
1032
1033                                 /* search interface */
1034                                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) calling to number '%s' interface '%s'\n", ea_endpoint->ep_serial, number, ifname[0]?ifname:"any interface");
1035                                 interface = hunt_interface(ifname[0]?ifname:NULL);
1036                                 if (!interface) {
1037                                         trace_header("INTERFACE (not found)", DIRECTION_NONE);
1038                                         add_trace("interface", NULL, "%s", ifname);
1039                                         end_trace();
1040                                         continue;
1041                                 }
1042                                 /* found interface */
1043                                 if (interface->remote) {
1044                                         admin = admin_first;
1045                                         while(admin) {
1046                                                 if (admin->remote_name[0] && !strcmp(admin->remote_name, interface->remote_app))
1047                                                         break;
1048                                                 admin = admin->next;
1049                                         }
1050                                         if (!admin) {
1051                                                 trace_header("INTERFACE (remote not connected)", DIRECTION_NONE);
1052                                                 add_trace("application", NULL, "%s", interface->remote_app);
1053                                                 end_trace();
1054                                                 continue;
1055                                         }
1056                                         SPRINT(portname, "%s-%d-out", interface->name, 0);
1057                                         port = new Premote(PORT_TYPE_REMOTE_OUT, portname, &port_settings, interface, admin->sock);
1058                                         earlyb = (interface->is_earlyb == IS_YES);
1059                                 } else
1060 #ifdef WITH_GSM_BS
1061                                 if (interface->gsm_bs) {
1062                                         SPRINT(portname, "%s-%d-out", interface->name, 0);
1063                                         port = new Pgsm_bs(PORT_TYPE_GSM_BS_OUT, portname, &port_settings, interface);
1064                                         earlyb = (interface->is_earlyb == IS_YES);
1065                                 } else
1066 #endif
1067 #ifdef WITH_GSM_MS
1068                                 if (interface->gsm_ms) {
1069                                         SPRINT(portname, "%s-%d-out", interface->name, 0);
1070                                         port = new Pgsm_ms(PORT_TYPE_GSM_MS_OUT, portname, &port_settings, interface);
1071                                         earlyb = (interface->is_earlyb == IS_YES);
1072                                 } else
1073 #endif
1074 #ifdef WITH_SIP
1075                                 if (interface->sip) {
1076                                         SPRINT(portname, "%s-%d-out", interface->name, 0);
1077                                         port = new Psip(PORT_TYPE_SIP_OUT, portname, &port_settings, interface);
1078                                         earlyb = (interface->is_earlyb == IS_YES);
1079                                 } else
1080 #endif
1081                                 {
1082 #ifdef WITH_MISDN
1083                                         /* hunt for mISDNport and create Port */
1084                                         mISDNport = hunt_port(ifname[0]?ifname:NULL, &channel);
1085                                         if (!mISDNport) {
1086                                                 trace_header("INTERFACE (too busy)", DIRECTION_NONE);
1087                                                 add_trace("interface", NULL, "%s", ifname[0]?ifname:"any interface");
1088                                                 end_trace();
1089                                                 continue;
1090                                         }
1091                                         /* creating EXTERNAL port*/
1092                                         SPRINT(portname, "%s-%d-out", mISDNport->ifport->interface->name, mISDNport->portnum);
1093
1094 #ifdef WITH_SS5
1095                                         if (mISDNport->ss5)
1096                                                 port = ss5_hunt_line(mISDNport);
1097                                         else
1098 #endif
1099 #ifdef ISDN_P_FXS_POTS
1100                                         if (mISDNport->pots)
1101                                                 port = new Pfxs(PORT_TYPE_POTS_FXS_OUT, mISDNport, portname, &port_settings, mISDNport->ifport->interface, mode);
1102                                         else
1103 #endif
1104                                                 port = new Pdss1((mISDNport->ntmode)?PORT_TYPE_DSS1_NT_OUT:PORT_TYPE_DSS1_TE_OUT, mISDNport, portname, &port_settings, mISDNport->ifport->interface, channel, mISDNport->ifport->channel_force, mode);
1105                                         earlyb = mISDNport->earlyb;
1106 #else
1107                                         trace_header("INTERFACE (has no function)", DIRECTION_NONE);
1108                                         add_trace("interface", NULL, "%s", ifname);
1109                                         end_trace();
1110                                         continue;
1111 #endif
1112                                 }
1113                                 if (!port)
1114                                         FATAL("No memory for Port instance\n");
1115                                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) created port %s\n", ea_endpoint->ep_serial, port->p_name);
1116                                 memset(&dialinginfo, 0, sizeof(dialinginfo));
1117                                 if (e_dialinginfo.keypad[0])
1118                                         SCPY(dialinginfo.keypad, number);
1119                                 else
1120                                         SCPY(dialinginfo.id, number);
1121                                 dialinginfo.itype = INFO_ITYPE_ISDN;
1122                                 dialinginfo.ntype = e_dialinginfo.ntype;
1123                                 dialinginfo.sending_complete = e_dialinginfo.sending_complete;
1124                                 portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, earlyb);
1125                                 if (!portlist) {
1126                                         PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
1127                                         delete port;
1128                                         continue;
1129                                 }
1130         //printf("EXTERNAL caller=%s,id=%s,dial=%s\n", param.setup.networkid, param.setup.callerinfo.id, param.setup.dialinginfo.id);
1131                                 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_SETUP);
1132                                 memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
1133                                 memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
1134                                 memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
1135                                 memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
1136                                 memcpy(&message->param.setup.rtpinfo, &e_rtpinfo, sizeof(struct rtp_info));
1137         //terminal                      SCPY(message->param.setup.from_terminal, e_ext.number);
1138         //terminal                      if (e_dialinginfo.id)
1139         //terminal                              SCPY(message->param.setup.to_terminal, e_dialinginfo.id);
1140                                         /* handle restricted caller ids */
1141                                 apply_callerid_restriction(&e_ext, message->param.setup.callerinfo.id, &message->param.setup.callerinfo.ntype, &message->param.setup.callerinfo.present, &message->param.setup.callerinfo.screen, message->param.setup.callerinfo.extension, message->param.setup.callerinfo.name);
1142                                 apply_callerid_restriction(&e_ext, message->param.setup.callerinfo.id2, &message->param.setup.callerinfo.ntype2, &message->param.setup.callerinfo.present2, &message->param.setup.callerinfo.screen2, message->param.setup.callerinfo.extension, message->param.setup.callerinfo.name);
1143                                 apply_callerid_restriction(&e_ext, message->param.setup.redirinfo.id, &message->param.setup.redirinfo.ntype, &message->param.setup.redirinfo.present, 0, message->param.setup.redirinfo.extension, NULL);
1144                                 /* display callerid if desired for extension */
1145                                 SCPY(message->param.setup.callerinfo.display, apply_callerid_display(message->param.setup.callerinfo.id, message->param.setup.callerinfo.itype, message->param.setup.callerinfo.ntype, message->param.setup.callerinfo.present, message->param.setup.callerinfo.screen, message->param.setup.callerinfo.extension, message->param.setup.callerinfo.name));
1146                                 message_put(message);
1147                                 logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
1148                                 anycall = 1;
1149
1150                                 /* found an interface
1151                                  * continue only if + is given, so every interface is calles parallel */
1152                                 if (e_dialinginfo.interfaces[0] != '+')
1153                                         break;
1154                         } while (*ifname_p);
1155                 } while(*number_p);
1156
1157                 /* now we have all ports created */
1158                 if (!anycall) {
1159                         trace_header("INTERFACE (no free ports found)", DIRECTION_NONE);
1160                         end_trace();
1161                         if (!ea_endpoint->ep_join_id)
1162                                 break;
1163                         release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOCHANNEL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYPE, join, port */
1164                         return; /* must exit here */
1165                 }
1166                 break;
1167         }
1168
1169 }
1170
1171 int action_timeout(struct lcr_timer *timer, void *instance, int index)
1172 {
1173         class EndpointAppPBX *ea = (class EndpointAppPBX *)instance;
1174
1175         if (!ea->e_action || ea->e_state == EPOINT_STATE_CONNECT)
1176                 return 0;
1177
1178         unsched_timer(&ea->e_redial_timeout);
1179         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) current action timed out.\n", ea->ea_endpoint->ep_serial);
1180         ea->e_multipoint_cause = 0;
1181         ea->e_multipoint_location = 0;
1182         ea->new_state(EPOINT_STATE_IN_OVERLAP);
1183         ea->e_join_pattern = 0;
1184         ea->process_dialing(1);
1185         /* we must exit, because our endpoint might be gone */
1186
1187         return 0;
1188 }
1189
1190 int match_timeout(struct lcr_timer *timer, void *instance, int index)
1191 {
1192         class EndpointAppPBX *ea = (class EndpointAppPBX *)instance;
1193
1194         if (!ea->e_action) {
1195                 unsched_timer(&ea->e_redial_timeout);
1196                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) we got a match timeout.\n", ea->ea_endpoint->ep_serial);
1197                 ea->process_dialing(0);
1198                 /* we must exit, because our endpoint might be gone */
1199         }
1200
1201         return 0;
1202 }
1203
1204 int redial_timeout(struct lcr_timer *timer, void *instance, int index)
1205 {
1206         class EndpointAppPBX *ea = (class EndpointAppPBX *)instance;
1207
1208         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) starting redial.\n", ea->ea_endpoint->ep_serial);
1209
1210         ea->new_state(EPOINT_STATE_OUT_SETUP);
1211         /* call special setup routine */
1212         ea->out_setup(0);
1213
1214         return 0;
1215 }
1216
1217 int powerdial_timeout(struct lcr_timer *timer, void *instance, int index)
1218 {
1219         class EndpointAppPBX *ea = (class EndpointAppPBX *)instance;
1220
1221         /* leave power dialing on */
1222         ea->e_powerdial_on = 1;
1223         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) starting redial of powerdial.\n", ea->ea_endpoint->ep_serial);
1224
1225         /* redial */
1226         ea->e_ruleset = ruleset_main;
1227         if (ea->e_ruleset)
1228                 ea->e_rule = ea->e_ruleset->rule_first;
1229         ea->e_action = NULL;
1230         ea->new_state(EPOINT_STATE_IN_OVERLAP);
1231         ea->process_dialing(0);
1232
1233         return 0;
1234 }
1235
1236 int cfnr_timeout(struct lcr_timer *timer, void *instance, int index)
1237 {
1238         class EndpointAppPBX *ea = (class EndpointAppPBX *)instance;
1239         struct port_list *portlist;
1240         struct lcr_msg *message;
1241
1242         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call-forward-no-response time has expired, hanging up.\n", ea->ea_endpoint->ep_serial);
1243
1244         /* release all ports */
1245         while((portlist = ea->ea_endpoint->ep_portlist)) {
1246                 message = message_create(ea->ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_RELEASE);
1247                 message->param.disconnectinfo.cause = CAUSE_NORMAL; /* normal clearing */
1248                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1249                 message_put(message);
1250                 ea->logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
1251                 ea->ea_endpoint->free_portlist(portlist);
1252         }
1253         /* put on hold */
1254         message = message_create(ea->ea_endpoint->ep_serial, ea->ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
1255         message->param.audiopath = 0;
1256         message_put(message);
1257         /* indicate no patterns */
1258         message = message_create(ea->ea_endpoint->ep_serial, ea->ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_NOPATTERN);
1259         message_put(message);
1260         /* set setup state, since we have no response from the new join */
1261         ea->new_state(EPOINT_STATE_OUT_SETUP);
1262
1263         return 0;
1264 }
1265
1266 int cfnr_call_timeout(struct lcr_timer *timer, void *instance, int index)
1267 {
1268         class EndpointAppPBX *ea = (class EndpointAppPBX *)instance;
1269
1270         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call-forward-busy time has expired, calling the forwarded number: %s.\n", ea->ea_endpoint->ep_serial, ea->e_ext.cfnr);
1271         ea->out_setup(1);
1272
1273         return 0;
1274 }
1275
1276 int callback_timeout(struct lcr_timer *timer, void *instance, int index)
1277 {
1278         class EndpointAppPBX *ea = (class EndpointAppPBX *)instance;
1279
1280         if (ea->e_state == EPOINT_STATE_IDLE) {
1281                 /* epoint is idle, check callback */
1282                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) starting callback.\n", ea->ea_endpoint->ep_serial);
1283                 ea->new_state(EPOINT_STATE_OUT_SETUP);
1284                 ea->out_setup(0);
1285         }
1286
1287         return 0;
1288 }
1289
1290 int password_timeout(struct lcr_timer *timer, void *instance, int index)
1291 {
1292         class EndpointAppPBX *ea = (class EndpointAppPBX *)instance;
1293
1294         if (ea->e_action->index==ACTION_PASSWORD || ea->e_action->index==ACTION_PASSWORD_WRITE) {
1295                 struct port_list *portlist;
1296
1297                 ea->e_ruleset = ruleset_main;
1298                 if (ea->e_ruleset)
1299                         ea->e_rule = ea->e_ruleset->rule_first;
1300                 ea->e_action = NULL;
1301                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) password timeout %s\n", ea->ea_endpoint->ep_serial, ea->e_extdialing);
1302                 ea->trace_header("PASSWORD timeout", DIRECTION_NONE);
1303                 end_trace();
1304                 ea->e_connectedmode = 0;
1305                 ea->e_dtmf = 0;
1306                 ea->new_state(EPOINT_STATE_OUT_DISCONNECT);
1307                 portlist = ea->ea_endpoint->ep_portlist;
1308                 if (portlist) {
1309                         ea->message_disconnect_port(portlist, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, "");
1310                         ea->set_tone(portlist, "cause_10");
1311                 }
1312         }
1313
1314         return 0;
1315 }
1316
1317 /* doing a hookflash */
1318 void EndpointAppPBX::hookflash(void)
1319 {
1320         class Port *port;
1321         time_t now;
1322
1323         /* be sure that we are active */
1324         notify_active();
1325         e_tx_state = NOTIFY_STATE_ACTIVE;
1326
1327         trace_header("HOOKFLASH DTMF", DIRECTION_NONE);
1328         end_trace();
1329         if (ea_endpoint->ep_use > 1) {
1330                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot hooflash while child process is running.\n", ea_endpoint->ep_serial);
1331                 return;
1332         }
1333         /* dialtone after pressing the hash key */
1334         process_hangup(e_join_cause, e_join_location);
1335         e_multipoint_cause = 0;
1336         e_multipoint_location = 0;
1337         port = find_port_id(ea_endpoint->ep_portlist->port_id);
1338         if (port) {
1339                 port->set_echotest(0);
1340         }
1341         if (ea_endpoint->ep_join_id) {
1342                 release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYPE, join, port */
1343         }
1344         e_ruleset = ruleset_main;
1345         if (e_ruleset)
1346                 e_rule = e_ruleset->rule_first;
1347         e_action = NULL;
1348         new_state(EPOINT_STATE_IN_OVERLAP);
1349         e_connectedmode = 1;
1350         SCPY(e_dialinginfo.id, e_ext.prefix);
1351         e_extdialing = e_dialinginfo.id;
1352         e_join_pattern = 0;
1353         if (e_dialinginfo.id[0]) {
1354                 set_tone(ea_endpoint->ep_portlist, "dialing");
1355                 process_dialing(0);
1356         } else {
1357                 set_tone(ea_endpoint->ep_portlist, "dialpbx");
1358         }
1359         time(&now);
1360         e_dtmf_time = now;
1361         e_dtmf_last = '\0';
1362 }
1363
1364
1365 /* messages from port
1366  */
1367 /* port MESSAGE_SETUP */
1368 void EndpointAppPBX::port_setup(struct port_list *portlist, int message_type, union parameter *param)
1369 {
1370         struct lcr_msg          *message;
1371         char                    buffer[256];
1372         int                     writeext;               /* flags need to write extension after modification */
1373         class Port              *port;
1374
1375         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
1376         
1377         portlist->port_type = param->setup.port_type;
1378         memcpy(&e_callerinfo, &param->setup.callerinfo, sizeof(e_callerinfo));
1379         memcpy(&e_dialinginfo, &param->setup.dialinginfo, sizeof(e_dialinginfo));
1380         memcpy(&e_redirinfo, &param->setup.redirinfo, sizeof(e_redirinfo));
1381         memcpy(&e_capainfo, &param->setup.capainfo, sizeof(e_capainfo));
1382         memcpy(&e_rtpinfo, &param->setup.rtpinfo, sizeof(e_rtpinfo));
1383
1384         /* convert (inter-)national number type */
1385         SCPY(e_dialinginfo.id, numberrize_callerinfo(e_dialinginfo.id, e_dialinginfo.ntype, options.national, options.international));
1386         e_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
1387
1388 //      e_dtmf = param->setup.dtmf;
1389         /* screen incoming caller id */
1390         if (e_callerinfo.interface[0]) {
1391                 do_screen(0, e_callerinfo.id, sizeof(e_callerinfo.id), &e_callerinfo.ntype, &e_callerinfo.present, e_callerinfo.interface);
1392                 do_screen(0, e_callerinfo.id2, sizeof(e_callerinfo.id2), &e_callerinfo.ntype2, &e_callerinfo.present2, e_callerinfo.interface);
1393                 do_screen(0, e_redirinfo.id, sizeof(e_redirinfo.id), &e_redirinfo.ntype, &e_redirinfo.present, e_callerinfo.interface);
1394         }
1395
1396         /* process extension */
1397         if (e_callerinfo.itype == INFO_ITYPE_ISDN_EXTENSION) {
1398                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming call is extension\n", ea_endpoint->ep_serial);
1399                 /* port makes call from extension */
1400                 SCPY(e_callerinfo.extension, e_callerinfo.id);
1401                 SCPY(e_ext.number, e_callerinfo.extension);
1402                 SCPY(e_extension_interface, e_callerinfo.interface);
1403         } else {
1404                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming call is external or voip\n", ea_endpoint->ep_serial);
1405         }
1406
1407         if (e_callerinfo.itype == INFO_ITYPE_ISDN_EXTENSION) {
1408                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call from extension '%s'\n", ea_endpoint->ep_serial, e_ext.number);
1409
1410                 /* get extension's info about caller */
1411                 if (!read_extension(&e_ext, e_ext.number)) {
1412                         /* extension doesn't exist */
1413                         trace_header("EXTENSION (not created)", DIRECTION_IN);
1414                         add_trace("extension", NULL, "%s", e_ext.number);
1415                         end_trace();
1416                         message_disconnect_port(portlist, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, "");
1417                         new_state(EPOINT_STATE_OUT_DISCONNECT);
1418                         set_tone(portlist, "cause_80"); /* pbx cause: extension not authorized */
1419                         e_ext.number[0] = '\0'; /* no terminal */
1420                         return;
1421                 }
1422                 writeext = 0;
1423
1424                 /* put prefix (next) in front of e_dialinginfo.id */
1425                 if (e_ext.next[0]) {
1426                         SPRINT(buffer, "%s%s", e_ext.next, e_dialinginfo.id);
1427                         SCPY(e_dialinginfo.id, buffer);
1428                         e_ext.next[0] = '\0';
1429                         writeext = 1;
1430                 } else if (e_ext.prefix[0]) {
1431                         SPRINT(buffer, "%s%s", e_ext.prefix, e_dialinginfo.id);
1432                         SCPY(e_dialinginfo.id, buffer);
1433                 }
1434
1435                 /* screen caller id by extension's config */
1436                 e_callerinfo.screen = INFO_SCREEN_NETWORK;
1437                 if (e_ext.name[0])
1438                         SCPY(e_callerinfo.name, e_ext.name);
1439                 /* use caller id (or if exist: id_next_call) for this call */
1440                 if (e_ext.id_next_call_present >= 0) {
1441                         SCPY(e_callerinfo.id, e_ext.id_next_call);
1442                         /* if we restrict the pesentation */
1443                         if (e_ext.id_next_call_present==INFO_PRESENT_ALLOWED && e_callerinfo.present==INFO_PRESENT_RESTRICTED)
1444                                 e_callerinfo.present = INFO_PRESENT_RESTRICTED;
1445                         else    e_callerinfo.present = e_ext.id_next_call_present;
1446                         e_callerinfo.ntype = e_ext.id_next_call_type;
1447                         e_ext.id_next_call_present = -1;
1448                         writeext = 1;
1449                 } else {
1450                         SCPY(e_callerinfo.id, e_ext.callerid);
1451                         /* if we restrict the pesentation */
1452                         if (e_ext.callerid_present==INFO_PRESENT_ALLOWED && e_callerinfo.present==INFO_PRESENT_RESTRICTED)
1453                                 e_callerinfo.present = INFO_PRESENT_RESTRICTED;
1454                         else    e_callerinfo.present = e_ext.callerid_present;
1455                         e_callerinfo.ntype = e_ext.callerid_type;
1456                 }
1457                 e_callerinfo.ntype2 = INFO_NTYPE_NOTPRESENT;
1458
1459                 /* extension is written */
1460                 if (writeext)
1461                         write_extension(&e_ext, e_ext.number);
1462
1463                 /* set volume of rx and tx */
1464                 if (param->setup.callerinfo.itype == INFO_ITYPE_ISDN_EXTENSION)
1465                 if (e_ext.tx_gain!=0 || e_ext.rx_gain!=0) {
1466                         message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_mISDNSIGNAL);
1467                         message->param.mISDNsignal.message = mISDNSIGNAL_VOLUME;
1468                         message->param.mISDNsignal.rx_gain = e_ext.tx_gain;
1469                         message->param.mISDNsignal.tx_gain = e_ext.rx_gain;
1470                         message_put(message);
1471                 }
1472
1473                 /* start recording if enabled */
1474                 if (e_ext.record!=CODEC_OFF && (e_capainfo.bearer_capa==INFO_BC_SPEECH || e_capainfo.bearer_capa==INFO_BC_AUDIO)) {
1475                         /* check if we are a terminal */
1476                         if (e_ext.number[0] == '\0')
1477                                 PERROR("Port(%d) cannot record because we are not a terminal\n", ea_endpoint->ep_serial);
1478                         else {
1479                                 port = find_port_id(portlist->port_id);
1480                                 if (port)
1481                                         port->open_record(e_ext.record, 0, 0, e_ext.number, e_ext.anon_ignore, "", 0);
1482                         }
1483                 }
1484         } else {
1485                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call from external port\n", ea_endpoint->ep_serial);
1486                 /* no terminal identification */
1487                 e_ext.number[0] = '\0';
1488                 e_extension_interface[0] = '\0';
1489                 memset(&e_ext, 0, sizeof(e_ext));
1490                 e_ext.rights = 4; /* right to dial internat */
1491         }
1492
1493         /* incoming call */
1494         e_ruleset = ruleset_main;
1495         if (e_ruleset)
1496                 e_rule = e_ruleset->rule_first;
1497         e_action = NULL;
1498         e_extdialing = e_dialinginfo.id;
1499         new_state(EPOINT_STATE_IN_SETUP);
1500         if (e_dialinginfo.id[0]) {
1501                 set_tone(portlist, "dialing");
1502         } else {
1503                 if (e_ext.number[0])
1504                         set_tone(portlist, "dialpbx");
1505                 else
1506                         set_tone(portlist, "dialtone");
1507         }
1508         process_dialing(0);
1509         if (e_state == EPOINT_STATE_IN_SETUP) {
1510                 /* request MORE info, if not already at higher state */
1511                 new_state(EPOINT_STATE_IN_OVERLAP);
1512                 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_OVERLAP);
1513                 message_put(message);
1514                 logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
1515         }
1516 }
1517
1518 /* port MESSAGE_INFORMATION */
1519 void EndpointAppPBX::port_information(struct port_list *portlist, int message_type, union parameter *param)
1520 {
1521         struct lcr_msg          *message;
1522
1523         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
1524
1525         /* ignore information message without digit information */
1526         if (!param->information.id[0])
1527                 return;
1528
1529         e_overlap = 1;
1530
1531         /* turn off dtmf detection, in case dtmf is sent with keypad information */
1532         if (e_dtmf) {
1533                 trace_header("DTMF (disabling due to keypad)", DIRECTION_IN);
1534                 end_trace();
1535                 e_dtmf = 0;
1536         }
1537
1538         /* if vbox_play is done, the information are just used as they come */
1539         if (e_action)
1540         if (e_action->index == ACTION_VBOX_PLAY) {
1541                 /* concat dialing string */
1542                 SCAT(e_dialinginfo.id, param->information.id);
1543                 process_dialing(0);
1544                 return;
1545         }
1546
1547         /* keypad when disconnect but in connected mode */
1548         if (e_state==EPOINT_STATE_OUT_DISCONNECT && e_connectedmode) {
1549                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) keypad information received after disconnect: %s.\n", ea_endpoint->ep_serial, param->information.id);
1550                 /* processing keypad function */
1551                 if (param->information.id[0] == '0') {
1552                         hookflash();
1553                 }
1554                 return;
1555         }
1556
1557         /* keypad when connected */
1558         if (e_state == EPOINT_STATE_CONNECT || e_state == EPOINT_STATE_IN_ALERTING) {
1559                 if (e_enablekeypad) {
1560                         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, message_type);
1561                         memcpy(&message->param, param, sizeof(union parameter));
1562                         message_put(message);
1563                         return;
1564                 }
1565                 if (e_ext.keypad) {
1566                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) keypad information received during connect: %s.\n", ea_endpoint->ep_serial, param->information.id);
1567                         /* processing keypad function */
1568                         if (param->information.id[0] == '0') {
1569                                 hookflash();
1570                         }
1571                         if (param->information.id[0])
1572                                 keypad_function(param->information.id[0]);
1573                 } else {
1574                         if (e_ext.number[0])
1575                                 trace_header("KEYPAD (not enabled by extension's settings)", DIRECTION_IN);
1576                         else
1577                                 trace_header("KEYPAD (not enabled for external interfaces)", DIRECTION_IN);
1578                         end_trace();
1579                 }
1580                 return;
1581         }
1582         if (e_state != EPOINT_STATE_IN_OVERLAP) {
1583                 if (e_ext.number[0])
1584                         trace_header("KEYPAD (ignored, not connected and not dialing)", DIRECTION_IN);
1585                 else
1586                         trace_header("KEYPAD (not enabled for external interfaces)", DIRECTION_IN);
1587                 end_trace();
1588                 return;
1589         }
1590         if (!param->information.id[0])
1591                 return;
1592         if (e_dialinginfo.id[0]=='\0' && !e_action) {
1593                 set_tone(portlist, "dialing");
1594         }
1595         if (e_action)
1596         if (e_action->index==ACTION_OUTDIAL
1597          || e_action->index==ACTION_EXTERNAL) {
1598                 if (!e_extdialing)
1599                         set_tone(portlist, "dialing");
1600                 else if (!e_extdialing[0])
1601                         set_tone(portlist, "dialing");
1602         }
1603         /* concat dialing string */
1604         SCAT(e_dialinginfo.id, param->information.id);
1605         process_dialing(0);
1606 }
1607
1608 /* port MESSAGE_DTMF */
1609 void EndpointAppPBX::port_dtmf(struct port_list *portlist, int message_type, union parameter *param)
1610 {
1611         time_t now;
1612         struct lcr_msg          *message;
1613
1614         time(&now);
1615
1616         /* only if dtmf detection is enabled */
1617         if (!e_dtmf) {
1618                 trace_header("DTMF (disabled)", DIRECTION_IN);
1619                 end_trace();
1620                 return;
1621         }
1622         trace_header("DTMF", DIRECTION_IN);
1623         add_trace("digit", NULL, "%c", param->dtmf);
1624         end_trace();
1625
1626 #if 0
1627 NOTE: vbox is now handled due to overlap state
1628         /* if vbox_play is done, the dtmf digits are just used as they come */
1629         if (e_action)
1630         if (e_action->index == ACTION_VBOX_PLAY) {
1631                 /* concat dialing string */
1632                 if (strlen(e_dialinginfo.id)+1 < sizeof(e_dialinginfo.id)) {
1633                         e_dialinginfo.id[strlen(e_dialinginfo.id)+1] = '\0';
1634                         e_dialinginfo.id[strlen(e_dialinginfo.id)] = param->dtmf;
1635                         process_dialing(0);
1636                 }
1637                 /* continue to process *X# sequences */
1638         }
1639 #endif
1640
1641         /* check for *X# sequence */
1642         if (e_state == EPOINT_STATE_CONNECT || e_state == EPOINT_STATE_IN_ALERTING) {
1643                 if (e_enablekeypad) {
1644                         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, message_type);
1645                         memcpy(&message->param, param, sizeof(union parameter));
1646                         message_put(message);
1647                         return;
1648                 }
1649                 if (e_dtmf_time+3 < now) {
1650                         /* the last digit was too far in the past to be a sequence */
1651                         if (param->dtmf == '*')
1652                                 /* only start is allowed in the sequence */
1653                                 e_dtmf_last = '*';
1654                         else
1655                                 e_dtmf_last = '\0';
1656                 } else {
1657                         /* we have a sequence of digits, see what we got */
1658                         if (param->dtmf == '*')
1659                                 e_dtmf_last = '*';
1660                         else if (param->dtmf>='0' && param->dtmf<='9') {
1661                                 /* we need to have a star before we receive the digit of the sequence */
1662                                 if (e_dtmf_last == '*')
1663                                         e_dtmf_last = param->dtmf;
1664                         } else if (param->dtmf == '#') {
1665                                 /* the hash key */
1666                                 if (e_dtmf_last>='0' && e_dtmf_last<='9') {
1667                                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dtmf sequence *%c# detected.\n", ea_endpoint->ep_serial, e_dtmf_last);
1668                                         if (e_dtmf_last == '0') {
1669                                                 hookflash();
1670                                                 return;
1671                                         }
1672                                         /* processing keypad function */
1673                                         if (param->dtmf)
1674                                                 keypad_function(e_dtmf_last);
1675                                         e_dtmf_last = '\0';
1676                                 }
1677                         }
1678                 }
1679
1680                 /* set last time of dtmf */
1681                 e_dtmf_time = now;
1682                 return;
1683         }
1684
1685         /* check for ## hookflash during dialing */
1686         if (e_action)
1687         if (e_action->index==ACTION_PASSWORD
1688          || e_action->index==ACTION_PASSWORD_WRITE)
1689                 goto password;
1690         if (param->dtmf=='#') { /* current digit is '#' */
1691                 if (e_state==EPOINT_STATE_IN_DISCONNECT
1692                  || (e_state!=EPOINT_STATE_CONNECT && e_dtmf_time+3>=now && e_dtmf_last=='#')) { /* when disconnected, just #. when dialing, ##. */
1693                         hookflash();
1694                         return;
1695                 } else {
1696                         e_dtmf_time = now;
1697                         e_dtmf_last = '#';
1698                 }
1699         } else {
1700                 password:
1701                 e_dtmf_time = now;
1702                 e_dtmf_last = '\0';
1703         }
1704         
1705
1706         /* dialing using dtmf digit */
1707         if (e_state==EPOINT_STATE_IN_OVERLAP){ // && e_state==e_connectedmode)
1708                 if (e_dialinginfo.id[0]=='\0' && !e_action) {
1709                         set_tone(portlist, "dialing");
1710                 }
1711                 /* concat dialing string */
1712                 if (strlen(e_dialinginfo.id)+1 < sizeof(e_dialinginfo.id)) {
1713                         e_dialinginfo.id[strlen(e_dialinginfo.id)+1] = '\0';
1714                         e_dialinginfo.id[strlen(e_dialinginfo.id)] = param->dtmf;
1715                         process_dialing(0);
1716                 }
1717         }
1718 }
1719
1720 /* port MESSAGE_CRYPT */
1721 void EndpointAppPBX::port_crypt(struct port_list *portlist, int message_type, union parameter *param)
1722 {
1723 #ifdef WITH_CRYPT
1724         /* send crypt response to cryptman */
1725         if (param->crypt.type == CR_MESSAGE_IND)
1726                 cryptman_msg2man(param->crypt.data, param->crypt.len);
1727         else
1728                 cryptman_message(param->crypt.type, param->crypt.data, param->crypt.len);
1729 #endif
1730 }
1731
1732 /* port MESSAGE_OVERLAP */
1733 void EndpointAppPBX::port_overlap(struct port_list *portlist, int message_type, union parameter *param)
1734 {
1735         struct lcr_msg *message;
1736
1737         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
1738
1739         /* signal to call tool */
1740         admin_call_response(e_adminid, ADMIN_CALL_SETUP_ACK, "", 0, 0, 0);
1741
1742         if (e_dialing_queue[0] && portlist) {
1743                 /* send what we have not dialed yet, because we had no setup complete */
1744                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing pending digits: '%s'\n", ea_endpoint->ep_serial, e_dialing_queue);
1745                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_INFORMATION);
1746                 SCPY(message->param.information.id, e_dialing_queue);
1747                 message->param.information.ntype = INFO_NTYPE_UNKNOWN;
1748                 message_put(message);
1749                 logmessage(message->type, &message->param, ea_endpoint->ep_portlist->port_id, DIRECTION_OUT);
1750                 e_dialing_queue[0] = '\0';
1751         }
1752         /* check if pattern is available */
1753         if (!ea_endpoint->ep_portlist->next && portlist->early_b) { /* one port_list relation and tones available */
1754                 /* indicate patterns */
1755                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_PATTERN);
1756                 message_put(message);
1757
1758                 /* connect audio, if not already */
1759                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
1760                 message->param.audiopath = 1;
1761                 message_put(message);
1762         } else {
1763                 /* indicate no patterns */
1764                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_NOPATTERN);
1765                 message_put(message);
1766
1767                 /* disconnect audio, if not already */
1768                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
1769                 message->param.audiopath = 0;
1770                 message_put(message);
1771         }
1772         new_state(EPOINT_STATE_OUT_OVERLAP);
1773         /* if we are in a join */
1774         if (ea_endpoint->ep_join_id) { 
1775                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, message_type);
1776                 memcpy(&message->param, param, sizeof(union parameter));
1777                 message_put(message);
1778         }
1779 }
1780
1781 /* port MESSAGE_PROCEEDING */
1782 void EndpointAppPBX::port_proceeding(struct port_list *portlist, int message_type, union parameter *param)
1783 {
1784         struct lcr_msg *message;
1785
1786         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
1787
1788         /* signal to call tool */
1789         admin_call_response(e_adminid, ADMIN_CALL_PROCEEDING, "", 0, 0, 0);
1790
1791         e_state = EPOINT_STATE_OUT_PROCEEDING;
1792         /* check if pattern is availatle */
1793         if (!ea_endpoint->ep_portlist->next && (portlist->early_b || portlist->port_type==PORT_TYPE_VBOX_OUT)) { /* one port_list relation and tones available */
1794                 /* indicate patterns */
1795                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_PATTERN);
1796                 message_put(message);
1797
1798                 /* connect audio, if not already */
1799                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
1800                 message->param.audiopath = 1;
1801                 message_put(message);
1802         } else {
1803                 /* indicate no patterns */
1804                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_NOPATTERN);
1805                 message_put(message);
1806
1807                 /* disconnect audio, if not already */
1808                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
1809                 message->param.audiopath = 0;
1810                 message_put(message);
1811         }
1812         /* if we are in a call */
1813         if (ea_endpoint->ep_join_id) { 
1814                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, message_type);
1815                 memcpy(&message->param, param, sizeof(union parameter));
1816                 message_put(message);
1817         }
1818 }
1819
1820 /* port MESSAGE_ALERTING */
1821 void EndpointAppPBX::port_alerting(struct port_list *portlist, int message_type, union parameter *param)
1822 {
1823         struct lcr_msg *message;
1824
1825         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
1826
1827         /* signal to call tool */
1828         admin_call_response(e_adminid, ADMIN_CALL_ALERTING, "", 0, 0, 0);
1829 //#warning hack!!
1830 //      if (e_adminid)
1831 //              set_tone(portlist, "hold");
1832
1833         new_state(EPOINT_STATE_OUT_ALERTING);
1834         /* check if pattern is available */
1835         if (!ea_endpoint->ep_portlist->next && (portlist->early_b || portlist->port_type==PORT_TYPE_VBOX_OUT)) { /* one port_list relation and tones available */
1836                 /* indicate patterns */
1837                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_PATTERN);
1838                 message_put(message);
1839
1840                 /* connect audio, if not already */
1841                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
1842                 message->param.audiopath = 1;
1843                 message_put(message);
1844         } else {
1845                 /* indicate no patterns */
1846                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_NOPATTERN);
1847                 message_put(message);
1848
1849                 /* disconnect audio, if not already */
1850                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
1851                 message->param.audiopath = 0;
1852                 message_put(message);
1853         }
1854         /* if we are in a call */
1855         if (ea_endpoint->ep_join_id) { 
1856                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, message_type);
1857                 memcpy(&message->param, param, sizeof(union parameter));
1858                 message_put(message);
1859         }
1860 }
1861
1862 /* port MESSAGE_CONNECT */
1863 void EndpointAppPBX::port_connect(struct port_list *portlist, int message_type, union parameter *param)
1864 {
1865         struct lcr_msg *message;
1866         char buffer[256];
1867         unsigned int port_id = portlist->port_id;
1868         struct port_list *tportlist;
1869         class Port *port;
1870         time_t now;
1871
1872         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
1873
1874         /* signal to call tool */
1875         admin_call_response(e_adminid, ADMIN_CALL_CONNECT, numberrize_callerinfo(param->connectinfo.id,param->connectinfo.ntype, options.national, options.international), 0, 0, 0);
1876
1877         memcpy(&e_connectinfo, &param->connectinfo, sizeof(e_connectinfo));
1878         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) removing all other ports (start)\n", ea_endpoint->ep_serial);
1879         while(ea_endpoint->ep_portlist->next) { /* as long as we have at least two ports */
1880                 tportlist = ea_endpoint->ep_portlist;
1881                 if (tportlist->port_id == port_id) /* if the first portlist is the calling one, the second must be a different one */
1882                         tportlist = tportlist->next;
1883                 if (tportlist->port_id == port_id)
1884                         FATAL("EPOINT(%d) this should not happen since the portlist list must not have two links to the same port - exitting.\n");
1885                 message = message_create(ea_endpoint->ep_serial, tportlist->port_id, EPOINT_TO_PORT, MESSAGE_RELEASE);
1886                 message->param.disconnectinfo.cause = CAUSE_NONSELECTED; /* non selected user clearing */
1887                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1888                 message_put(message);
1889                 logmessage(message->type, &message->param, tportlist->port_id, DIRECTION_OUT);
1890                 ea_endpoint->free_portlist(tportlist);
1891         }
1892         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) removing all other ports (end)\n", ea_endpoint->ep_serial);
1893
1894         time(&now);
1895         e_start = now;
1896
1897         if (e_callerinfo.interface[0])
1898                 do_screen(0, e_connectinfo.id, sizeof(e_connectinfo.id), &e_connectinfo.ntype, &e_connectinfo.present, e_connectinfo.interface);
1899
1900         /* screen connected name */
1901         if (e_ext.name[0])
1902                 SCPY(e_connectinfo.name, e_ext.name);
1903
1904         /* add internal id to colp */
1905         SCPY(e_connectinfo.extension, e_ext.number);
1906
1907         /* we store the connected port number */
1908         SCPY(e_extension_interface, e_connectinfo.interface);
1909
1910         /* for internal and am calls, we get the extension's id */
1911         if (portlist->port_type==PORT_TYPE_VBOX_OUT || e_ext.colp==COLP_HIDE) {
1912                 SCPY(e_connectinfo.id, e_ext.callerid);
1913                 SCPY(e_connectinfo.extension, e_ext.number);
1914                 e_connectinfo.itype = INFO_ITYPE_ISDN_EXTENSION;
1915                 e_connectinfo.ntype = e_ext.callerid_type;
1916                 e_connectinfo.present = e_ext.callerid_present;
1917         }
1918         if (portlist->port_type==PORT_TYPE_VBOX_OUT) {
1919                 e_connectinfo.itype = INFO_ITYPE_VBOX;
1920                 e_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
1921         }
1922
1923         new_state(EPOINT_STATE_CONNECT);
1924
1925         /* set volume of rx and tx */
1926         if (e_ext.tx_gain!=0 || e_ext.rx_gain!=0) {
1927                 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_mISDNSIGNAL);
1928                 message->param.mISDNsignal.message = mISDNSIGNAL_VOLUME;
1929                 message->param.mISDNsignal.rx_gain = e_ext.tx_gain;
1930                 message->param.mISDNsignal.tx_gain = e_ext.rx_gain;
1931                 message_put(message);
1932         }
1933
1934         unsched_timer(&e_cfnr_timeout);
1935         unsched_timer(&e_cfnr_call_timeout);
1936         if (e_ext.number[0])
1937                 e_dtmf = 1; /* allow dtmf */
1938
1939         /* modify colp */
1940         /* other calls with no caller id (or not available for the extension) and force colp */
1941         if ((e_connectinfo.id[0]=='\0' || (e_connectinfo.present==INFO_PRESENT_RESTRICTED && !e_ext.anon_ignore))&& e_ext.colp==COLP_FORCE) {
1942                 e_connectinfo.ntype = INFO_NTYPE_NOTPRESENT;
1943                 if ((portlist->port_type & PORT_CLASS_DIR_MASK) == PORT_CLASS_DIR_OUT) {
1944                         /* external extension answered */
1945                         port = find_port_id(portlist->port_id);
1946                         if (port) {
1947                                 SCPY(e_connectinfo.id, nationalize_callerinfo(port->p_dialinginfo.id, &e_connectinfo.ntype, options.national, options.international));
1948                                 e_connectinfo.present = INFO_PRESENT_ALLOWED;
1949                         }
1950                 }
1951         }
1952
1953         /* send connect to join */
1954         if (ea_endpoint->ep_join_id) {
1955                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, message_type);
1956                 memcpy(&message->param.connectinfo, &e_connectinfo, sizeof(struct connect_info));
1957                 message_put(message);
1958
1959                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
1960                 message->param.audiopath = 1;
1961                 message_put(message);
1962         } else if (!e_adminid) {
1963                 /* callback */
1964                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) we have a callback, so we create a call with cbcaller: \"%s\".\n", ea_endpoint->ep_serial, e_cbcaller);
1965                 SCPY(e_ext.number, e_cbcaller);
1966                 new_state(EPOINT_STATE_IN_OVERLAP);
1967                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) callback from extension '%s'\n", ea_endpoint->ep_serial, e_ext.number);
1968
1969                 /* get extension's info about terminal */
1970                 if (!read_extension(&e_ext, e_ext.number)) {
1971                         /* extension doesn't exist */
1972                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) rejecting callback from not existing extension: '%s'\n", ea_endpoint->ep_serial, e_ext.number);
1973                         message_disconnect_port(portlist, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, "");
1974                         new_state(EPOINT_STATE_OUT_DISCONNECT);
1975                         set_tone(portlist, "cause_80"); /* pbx cause: extension not authorized */
1976                         return;
1977                 }
1978
1979                 /* put prefix in front of e_cbdialing */
1980                 SPRINT(buffer, "%s%s", e_ext.prefix, e_cbdialing);
1981                 SCPY(e_dialinginfo.id, buffer);
1982                 e_dialinginfo.itype = INFO_ITYPE_ISDN;
1983                 e_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
1984
1985                 /* use caller id (or if exist: id_next_call) for this call */
1986                 e_callerinfo.screen = INFO_SCREEN_NETWORK;
1987                 SCPY(e_callerinfo.extension, e_ext.number);
1988                 if (e_ext.id_next_call_present >= 0) {
1989                         SCPY(e_callerinfo.id, e_ext.id_next_call);
1990                         e_callerinfo.present = e_ext.id_next_call_present;
1991                         e_callerinfo.ntype = e_ext.id_next_call_type;
1992                         e_ext.id_next_call_present = -1;
1993                         /* extension is written */
1994                         write_extension(&e_ext, e_ext.number);
1995                 } else {
1996                         SCPY(e_callerinfo.id, e_ext.callerid);
1997                         e_callerinfo.present = e_ext.callerid_present;
1998                         e_callerinfo.ntype = e_ext.callerid_type;
1999                 }
2000                 e_callerinfo.ntype2 = INFO_NTYPE_NOTPRESENT;
2001
2002                 e_connectedmode = 1; /* dtmf-hangup & disconnect prevention */
2003                 e_dtmf = 1;
2004
2005                 /* check if caller id is NOT authenticated */
2006                 if (!parse_callbackauth(e_ext.number, &e_callbackinfo)) {
2007                         /* make call state to enter password */
2008                         new_state(EPOINT_STATE_IN_OVERLAP);
2009                         e_action = &action_password_write;
2010                         unsched_timer(&e_match_timeout);
2011                         e_match_to_action = NULL;
2012                         e_dialinginfo.id[0] = '\0';
2013                         e_extdialing = strchr(e_dialinginfo.id, '\0');
2014                         schedule_timer(&e_password_timeout, 20, 0);
2015                         process_dialing(0);
2016                 } else {
2017                         /* incoming call (callback) */
2018                         e_ruleset = ruleset_main;
2019                         if (e_ruleset)
2020                                 e_rule = e_ruleset->rule_first;
2021                         e_action = NULL;
2022                         e_extdialing = e_dialinginfo.id;
2023                         if (e_dialinginfo.id[0]) {
2024                                 set_tone(portlist, "dialing");
2025                                 process_dialing(0);
2026                         } else {
2027                                 set_tone(portlist, "dialpbx");
2028                         }
2029                 }
2030         } else { /* testcall */
2031                 set_tone(portlist, "hold");
2032         }
2033
2034         /* start recording if enabled, not when answering machine answers */
2035         if (param->connectinfo.itype!=INFO_ITYPE_VBOX && e_ext.number[0] && e_ext.record!=CODEC_OFF && (e_capainfo.bearer_capa==INFO_BC_SPEECH || e_capainfo.bearer_capa==INFO_BC_AUDIO)) {
2036                 /* check if we are a terminal */
2037                 if (e_ext.number[0] == '\0')
2038                         PERROR("Port(%d) cannot record because we are not a terminal\n", ea_endpoint->ep_serial);
2039                 else {
2040                         port = find_port_id(portlist->port_id);
2041                         if (port)
2042                                 port->open_record(e_ext.record, 0, 0, e_ext.number, e_ext.anon_ignore, "", 0);
2043                 }
2044         }
2045 }
2046
2047 /* port MESSAGE_DISCONNECT MESSAGE_RELEASE */
2048 void EndpointAppPBX::port_disconnect_release(struct port_list *portlist, int message_type, union parameter *param)
2049 {
2050         struct lcr_msg  *message;
2051         char            buffer[256];
2052         unsigned int    port_id = portlist->port_id;
2053         int             cause,
2054                         location;
2055
2056         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
2057
2058         /* signal to call tool */
2059         admin_call_response(e_adminid, (message_type==MESSAGE_DISCONNECT)?ADMIN_CALL_DISCONNECT:ADMIN_CALL_RELEASE, "", param->disconnectinfo.cause, param->disconnectinfo.location, 0);
2060
2061 //#warning does this work? only disconnect when incoming port hat not already disconnected yet?
2062         if (e_state==EPOINT_STATE_IN_DISCONNECT && message_type!=MESSAGE_RELEASE){ // || e_state==EPOINT_STATE_OUT_DISCONNECT || e_state==EPOINT_STATE_IDLE)
2063                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are already disconnected.\n", ea_endpoint->ep_serial);
2064                 return;
2065         }
2066
2067         /* collect cause */
2068         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) current multipoint cause %d location %d, received cause %d location %d.\n", ea_endpoint->ep_serial, e_multipoint_cause, e_multipoint_location, param->disconnectinfo.cause, param->disconnectinfo.location);
2069         collect_cause(&e_multipoint_cause, &e_multipoint_location, param->disconnectinfo.cause, param->disconnectinfo.location);
2070         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) new multipoint cause %d location %d.\n", ea_endpoint->ep_serial, e_multipoint_cause, e_multipoint_location);
2071
2072         /* check if we have more than one portlist relation and we just ignore the disconnect */
2073         if (ea_endpoint->ep_portlist) if (ea_endpoint->ep_portlist->next) {
2074                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) the disconnect was from a multipoint call. we just release that relation.\n", ea_endpoint->ep_serial);
2075                 portlist = ea_endpoint->ep_portlist;
2076                 while(portlist) {
2077                         if (portlist->port_id == port_id)
2078                                 break;
2079                         portlist = portlist->next;
2080                 }
2081                 if (!portlist)
2082                         FATAL("EPOINT(%d) no portlist related to the calling port.\n", ea_endpoint->ep_serial);
2083                 if (message_type != MESSAGE_RELEASE) {
2084                         message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_RELEASE);
2085                         message->param.disconnectinfo.cause = CAUSE_NORMAL; /* normal clearing */
2086                         message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2087                         message_put(message);
2088                         logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
2089                 }
2090                 ea_endpoint->free_portlist(portlist);
2091                 return; /* one relation removed */ 
2092         }
2093         if (e_state == EPOINT_STATE_CONNECT) {
2094                 /* use cause from port after connect */
2095                 cause = param->disconnectinfo.cause;
2096                 location = param->disconnectinfo.location;
2097         } else {
2098                 /* use multipoint cause if no connect yet */
2099                 if (e_multipoint_cause) {
2100                         cause = e_multipoint_cause;
2101                         location = e_multipoint_location;
2102                 } else {
2103                         cause = CAUSE_NOUSER;
2104                         location = LOCATION_PRIVATE_LOCAL;
2105                 }
2106         }
2107
2108         unsched_timer(&e_cfnr_timeout);
2109         unsched_timer(&e_cfnr_call_timeout);
2110
2111         /* process hangup */
2112         process_hangup(e_join_cause, e_join_location);
2113         e_multipoint_cause = 0;
2114         e_multipoint_location = 0;
2115
2116         if (message_type == MESSAGE_DISCONNECT) {
2117                 /* tone to disconnected end */
2118                 SPRINT(buffer, "cause_%02x", cause);
2119                 if (ea_endpoint->ep_portlist)
2120                         set_tone(ea_endpoint->ep_portlist, buffer);
2121
2122                 new_state(EPOINT_STATE_IN_DISCONNECT);
2123         }
2124
2125         if (ea_endpoint->ep_join_id) {
2126                 int haspatterns = 0;
2127                 /* check if pattern is available */
2128                 if (ea_endpoint->ep_portlist)
2129                 if (!ea_endpoint->ep_portlist->next && ea_endpoint->ep_portlist->early_b)
2130                 if (joinpbx_countrelations(ea_endpoint->ep_join_id)==2 // we must count relations, in order not to disturb the conference ; NOTE: asterisk always counts two, since it is a point to point call 
2131                  && message_type != MESSAGE_RELEASE) // if we release, we are done
2132                         haspatterns = 1;
2133                 if (haspatterns) {
2134                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) the port has patterns.\n", ea_endpoint->ep_serial);
2135                         /* indicate patterns */
2136                         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_PATTERN);
2137                         message_put(message);
2138                         /* connect audio, if not already */
2139                         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
2140                         message->param.audiopath = 1;
2141                         message_put(message);
2142                         /* send disconnect */
2143                         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, message_type);
2144                         memcpy(&message->param, param, sizeof(union parameter));
2145                         message_put(message);
2146                         /* disable encryption if disconnected */
2147 //PERROR("REMOVE ME: state =%d, %d\n", e_crypt_state, e_crypt);
2148 #ifdef WITH_CRYPT
2149                         if (e_crypt_state)
2150                                 cryptman_message(CI_DISCONNECT_IND, NULL, 0);
2151 #endif
2152                         return;
2153                 } else {
2154                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) the port has no patterns.\n", ea_endpoint->ep_serial);
2155                 }
2156         }
2157         if (message_type == MESSAGE_RELEASE)
2158                 ea_endpoint->free_portlist(portlist);
2159         release(RELEASE_ALL, location, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYPE, callcause, portcause */
2160         return; /* must exit here */
2161 }
2162
2163 /* port MESSAGE_TIMEOUT */
2164 void EndpointAppPBX::port_timeout(struct port_list *portlist, int message_type, union parameter *param)
2165 {
2166         char cause[16];
2167
2168         trace_header("TIMEOUT", DIRECTION_IN);
2169         message_type = MESSAGE_DISCONNECT;
2170         switch (param->state) {
2171                 case PORT_STATE_OUT_SETUP:
2172                 case PORT_STATE_OUT_OVERLAP:
2173                 add_trace("state", NULL, "outgoing setup/dialing");
2174                 end_trace();
2175                 /* no user responding */
2176                 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOUSER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
2177                 return; /* must exit here */
2178
2179                 case PORT_STATE_IN_SETUP:
2180                 case PORT_STATE_IN_OVERLAP:
2181                 add_trace("state", NULL, "incoming setup/dialing");
2182                 param->disconnectinfo.cause = CAUSE_INVALID; /* number incomplete */
2183                 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2184                 break;
2185
2186                 case PORT_STATE_OUT_PROCEEDING:
2187                 add_trace("state", NULL, "outgoing proceeding");
2188                 end_trace();
2189                 param->disconnectinfo.cause = CAUSE_NOUSER; /* no user responding */
2190                 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2191                 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOUSER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
2192                 return; /* must exit here */
2193
2194                 case PORT_STATE_IN_PROCEEDING:
2195                 add_trace("state", NULL, "incoming proceeding");
2196                 param->disconnectinfo.cause = CAUSE_NOUSER;
2197                 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL; /* no user responding */
2198                 break;
2199
2200                 case PORT_STATE_OUT_ALERTING:
2201                 add_trace("state", NULL, "outgoing alerting");
2202                 end_trace();
2203                 param->disconnectinfo.cause = CAUSE_NOANSWER; /* no answer */
2204                 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2205                 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOANSWER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
2206                 return; /* must exit here */
2207
2208                 case PORT_STATE_CONNECT:
2209                 add_trace("state", NULL, "connect");
2210                 end_trace();
2211                 param->disconnectinfo.cause = CAUSE_NORMAL; /* normal */
2212                 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2213                 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
2214                 return; /* must exit here */
2215
2216                 case PORT_STATE_IN_ALERTING:
2217                 add_trace("state", NULL, "incoming alerting");
2218                 param->disconnectinfo.cause = CAUSE_NOANSWER;
2219                 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2220                 break;
2221
2222                 case PORT_STATE_IN_DISCONNECT:
2223                 case PORT_STATE_OUT_DISCONNECT:
2224                 add_trace("state", NULL, "disconnect");
2225                 end_trace();
2226                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) in this special case, we release due to disconnect timeout.\n", ea_endpoint->ep_serial);
2227                 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
2228                 return; /* must exit here */
2229
2230                 default:
2231                 param->disconnectinfo.cause = 31; /* normal unspecified */
2232                 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2233         }
2234         end_trace();
2235         /* release call, disconnect isdn */
2236         e_join_pattern = 0;
2237         new_state(EPOINT_STATE_OUT_DISCONNECT);
2238         SPRINT(cause, "cause_%02x", param->disconnectinfo.cause);
2239         SCPY(e_tone, cause);
2240         while(portlist) {
2241                 set_tone(portlist, cause);
2242                 message_disconnect_port(portlist, param->disconnectinfo.cause, param->disconnectinfo.location, "");
2243                 portlist = portlist->next;
2244         }
2245         release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYPE, join, port */
2246 }
2247
2248 /* port MESSAGE_NOTIFY */
2249 void EndpointAppPBX::port_notify(struct port_list *portlist, int message_type, union parameter *param)
2250 {
2251         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
2252
2253         struct lcr_msg *message;
2254
2255         /* signal to call tool */
2256         admin_call_response(e_adminid, ADMIN_CALL_NOTIFY, numberrize_callerinfo(param->notifyinfo.id,param->notifyinfo.ntype, options.national, options.international), 0, 0, param->notifyinfo.notify);
2257         if (param->notifyinfo.notify) {
2258                 e_rx_state = track_notify(e_rx_state, param->notifyinfo.notify);
2259         }
2260
2261         /* if we get notification from stack, local shows if we disabled/enabled audio stream */
2262         if (param->notifyinfo.local) switch(param->notifyinfo.notify) {
2263                 case INFO_NOTIFY_REMOTE_HOLD:
2264                 case INFO_NOTIFY_USER_SUSPENDED:
2265                 /* tell call about it */
2266                 if (ea_endpoint->ep_join_id) {
2267                         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
2268                         message->param.audiopath = 0;
2269                         message_put(message);
2270                 }
2271                 break;
2272
2273                 case INFO_NOTIFY_REMOTE_RETRIEVAL:
2274                 case INFO_NOTIFY_USER_RESUMED:
2275                 /* set volume of rx and tx */
2276                 if (param->setup.callerinfo.itype == INFO_ITYPE_ISDN_EXTENSION)
2277                 if (e_ext.tx_gain!=0 || e_ext.rx_gain!=0)
2278                 if (portlist) {
2279                         message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_mISDNSIGNAL);
2280                         message->param.mISDNsignal.message = mISDNSIGNAL_VOLUME;
2281                         message->param.mISDNsignal.rx_gain = e_ext.tx_gain;
2282                         message->param.mISDNsignal.tx_gain = e_ext.rx_gain;
2283                         message_put(message);
2284                 }
2285                 /* set current tone */
2286                 if (portlist)
2287                         set_tone(portlist, e_tone);
2288                 /* tell call about it */
2289                 if (ea_endpoint->ep_join_id) {
2290                         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
2291                         message->param.audiopath = 1;
2292                         message_put(message);
2293                 }
2294                 break;
2295         }
2296
2297         /* notify call if available */
2298         if (ea_endpoint->ep_join_id) {
2299                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_NOTIFY);
2300                 memcpy(&message->param.notifyinfo, &param->notifyinfo, sizeof(struct notify_info));
2301                 message_put(message);
2302         }
2303
2304 }
2305
2306 /* port MESSAGE_PROGRESS */
2307 void EndpointAppPBX::port_progress(struct port_list *portlist, int message_type, union parameter *param)
2308 {
2309         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
2310
2311         struct lcr_msg *message;
2312
2313         /* signal to call tool */
2314         admin_call_response(e_adminid, ADMIN_CALL_PROGRESS, "", 0, param->progressinfo.location, param->progressinfo.progress);
2315
2316         /* send progress to call if available */
2317         if (ea_endpoint->ep_join_id) {
2318                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_PROGRESS);
2319                 memcpy(&message->param.progressinfo, &param->progressinfo, sizeof(struct progress_info));
2320                 message_put(message);
2321         }
2322
2323 }
2324
2325 /* port MESSAGE_FACILITY */
2326 void EndpointAppPBX::port_facility(struct port_list *portlist, int message_type, union parameter *param)
2327 {
2328         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
2329
2330         struct lcr_msg *message;
2331
2332         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_FACILITY);
2333         memcpy(&message->param.facilityinfo, &param->facilityinfo, sizeof(struct facility_info));
2334         message_put(message);
2335 }
2336
2337 /* port MESSAGE_3PTY */
2338 void EndpointAppPBX::port_3pty(struct port_list *portlist, int message_type, union parameter *param)
2339 {
2340         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
2341
2342         struct lcr_msg *message;
2343         int rc;
2344
2345         /* 3PTY bridge */
2346         if (param->threepty.begin)
2347                 rc = join_3pty_dss1();
2348         else if (param->threepty.end)
2349                 rc = split_3pty();
2350         else
2351                 return;
2352
2353         message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_3PTY);
2354         message->param.threepty.begin = param->threepty.begin;
2355         message->param.threepty.end = param->threepty.end;
2356         if (rc < 0)
2357                 message->param.threepty.error = 1;
2358         else
2359                 message->param.threepty.result = 1;
2360         message->param.threepty.invoke_id = param->threepty.invoke_id;
2361         logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
2362         message_put(message);
2363 }
2364
2365 /* port MESSAGE_TRANSFER */
2366 void EndpointAppPBX::port_transfer(struct port_list *portlist, int message_type, union parameter *param)
2367 {
2368         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
2369
2370         class Port *port;
2371
2372         /* bridge for real */
2373         if (!(port = find_port_id(portlist->port_id)))
2374                 return;
2375         if ((port->p_type & PORT_CLASS_POTS_MASK) == PORT_CLASS_POTS_FXS)
2376                 join_join_fxs();
2377         else if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_DSS1)
2378                 join_join_dss1();
2379 }
2380
2381 /* port MESSAGE_SUSPEND */
2382 /* NOTE: before supending, the inactive-notification must be done in order to set call mixer */
2383 void EndpointAppPBX::port_suspend(struct port_list *portlist, int message_type, union parameter *param)
2384 {
2385         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
2386
2387         /* epoint is now parked */
2388         ea_endpoint->ep_park = 1;
2389         memcpy(ea_endpoint->ep_park_callid, param->parkinfo.callid, sizeof(ea_endpoint->ep_park_callid));
2390         ea_endpoint->ep_park_len = (param->parkinfo.len>8)?8:param->parkinfo.len;
2391
2392         /* remove port relation */
2393         ea_endpoint->free_portlist(portlist);
2394 }
2395
2396 /* port MESSAGE_RESUME */
2397 /* NOTE: before resume, the active-notification must be done in order to set call mixer */
2398 void EndpointAppPBX::port_resume(struct port_list *portlist, int message_type, union parameter *param)
2399 {
2400         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
2401
2402         /* epoint is now resumed */
2403         ea_endpoint->ep_park = 0;
2404
2405 }
2406
2407 /* port MESSAGE_ENABLEKEYPAD */
2408 void EndpointAppPBX::port_enablekeypad(struct port_list *portlist, int message_type, union parameter *param)
2409 {
2410         struct lcr_msg *message;
2411
2412         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
2413
2414         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_ENABLEKEYPAD);
2415         memcpy(&message->param, param, sizeof(union parameter));
2416         message_put(message);
2417 }
2418
2419
2420 /* port MESSAGE_DISABLE_DEJITTER */
2421 void EndpointAppPBX::port_disable_dejitter(struct port_list *portlist, int message_type, union parameter *param)
2422 {
2423         struct lcr_msg *message;
2424
2425         logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
2426
2427         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_DISABLE_DEJITTER);
2428         memcpy(&message->param, param, sizeof(union parameter));
2429         message_put(message);
2430 }
2431
2432
2433 /* port sends message to the endpoint
2434  */
2435 void EndpointAppPBX::ea_message_port(unsigned int port_id, int message_type, union parameter *param)
2436 {
2437         struct port_list *portlist;
2438
2439         portlist = ea_endpoint->ep_portlist;
2440         while(portlist) {
2441                 if (port_id == portlist->port_id)
2442                         break;
2443                 portlist = portlist->next;
2444         }
2445         if (!portlist) {
2446                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) warning: port is not related to this endpoint. This may happen, if port has been released after the message was created.\n", ea_endpoint->ep_serial);
2447                 return;
2448         }
2449
2450 //      PDEBUG(DEBUG_EPOINT, "received message %d (terminal %s, caller id %s)\n", message, e_ext.number, e_callerinfo.id);
2451         switch(message_type) {
2452                 case MESSAGE_TONE_EOF: /* tone is end of file */
2453                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) current tone is now end of file.\n", ea_endpoint->ep_serial);
2454                 if (e_action) {
2455                         if (e_action->index == ACTION_VBOX_PLAY) {
2456                                 vbox_message_eof();
2457                         }
2458                         if (e_action->index == ACTION_EFI) {
2459                                 efi_message_eof();
2460                         }
2461                 }
2462                 break;
2463
2464                 case MESSAGE_TONE_COUNTER: /* counter info received */
2465                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) received counter information: %d / %d seconds after start of tone.\n", ea_endpoint->ep_serial, param->counter.current, param->counter.max);
2466                 if (e_action)
2467                 if (e_action->index == ACTION_VBOX_PLAY) {
2468                         e_vbox_counter = param->counter.current;
2469                         if (param->counter.max >= 0)
2470                                 e_vbox_counter_max = param->counter.max;
2471                 }
2472                 break;
2473
2474                 /* PORT sends SETUP message */
2475                 case MESSAGE_SETUP:
2476                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming call from callerid=%s, dialing=%s\n", ea_endpoint->ep_serial, param->setup.callerinfo.id, param->setup.dialinginfo.id);
2477                 if (e_state!=EPOINT_STATE_IDLE) {
2478                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in idle state.\n", ea_endpoint->ep_serial);
2479                         break;
2480                 }
2481                 port_setup(portlist, message_type, param);
2482                 break;
2483
2484                 /* PORT sends INFORMATION message */
2485                 case MESSAGE_INFORMATION: /* additional digits received */
2486                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming call dialing more=%s (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, param->information.id, e_ext.number, e_callerinfo.id);
2487                 port_information(portlist, message_type, param);
2488                 break;
2489
2490                 /* PORT sends FACILITY message */
2491                 case MESSAGE_FACILITY:
2492                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming facility (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
2493                 port_facility(portlist, message_type, param);
2494                 break;
2495
2496                 case MESSAGE_3PTY:
2497                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming 3PTY facility (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
2498                 port_3pty(portlist, message_type, param);
2499                 break;
2500
2501                 case MESSAGE_TRANSFER:
2502                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming TRANSFER request (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
2503                 port_transfer(portlist, message_type, param);
2504                 break;
2505
2506                 /* PORT sends DTMF message */
2507                 case MESSAGE_DTMF: /* dtmf digits received */
2508                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dtmf digit=%c (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, param->dtmf, e_ext.number, e_callerinfo.id);
2509                 port_dtmf(portlist, message_type, param);
2510                 break;
2511
2512                 /* PORT sends CRYPT message */
2513                 case MESSAGE_CRYPT: /* crypt response received */
2514                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) crypt response=%d\n", ea_endpoint->ep_serial, param->crypt.type);
2515                 port_crypt(portlist, message_type, param);
2516                 break;
2517
2518                 /* PORT sends MORE message */
2519                 case MESSAGE_OVERLAP:
2520                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) outgoing call is accepted [overlap dialing] (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
2521                 if (e_state != EPOINT_STATE_OUT_SETUP) {
2522                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in setup state (for port_list: another portlist might have changed the state already).\n", ea_endpoint->ep_serial);
2523                         break;
2524                 }
2525                 port_overlap(portlist, message_type, param);
2526                 break;
2527
2528                 /* PORT sends PROCEEDING message */
2529                 case MESSAGE_PROCEEDING: /* port is proceeding */
2530                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) outgoing call is proceeding (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
2531                 if (e_state!=EPOINT_STATE_OUT_SETUP
2532                  && e_state!=EPOINT_STATE_OUT_OVERLAP) {
2533                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in overlap state (for port_list: another portlist might have changed the state already).\n", ea_endpoint->ep_serial);
2534                         break;
2535                 }
2536                 port_proceeding(portlist, message_type, param);
2537                 break;
2538
2539                 /* PORT sends ALERTING message */
2540                 case MESSAGE_ALERTING:
2541                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) outgoing call is ringing (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
2542                 if (e_state!=EPOINT_STATE_OUT_SETUP
2543                  && e_state!=EPOINT_STATE_OUT_OVERLAP
2544                  && e_state!=EPOINT_STATE_OUT_PROCEEDING) {
2545                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in setup or proceeding state (for port_list: another portlist might have changed the state already).\n", ea_endpoint->ep_serial);
2546                         break;
2547                 }
2548                 port_alerting(portlist, message_type, param);
2549                 break;
2550
2551                 /* PORT sends CONNECT message */
2552                 case MESSAGE_CONNECT:
2553                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) outgoing call connected to %s (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, e_connectinfo.id, e_ext.number, e_callerinfo.id);
2554                 if (e_state!=EPOINT_STATE_OUT_SETUP
2555                  && e_state!=EPOINT_STATE_OUT_OVERLAP
2556                  && e_state!=EPOINT_STATE_OUT_PROCEEDING
2557                  && e_state!=EPOINT_STATE_OUT_ALERTING) {
2558                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in setup, proceeding or alerting state.\n", ea_endpoint->ep_serial);
2559                         break;
2560                 }
2561                 port_connect(portlist, message_type, param);
2562                 break;
2563
2564                 /* PORT sends DISCONNECT message */
2565                 case MESSAGE_DISCONNECT: /* port is disconnected */
2566                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call disconnect with cause=%d location=%d (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, param->disconnectinfo.cause, param->disconnectinfo.location, e_ext.number, e_callerinfo.id);
2567                 port_disconnect_release(portlist, message_type, param);
2568                 break;
2569
2570                 /* PORT sends a RELEASE message */
2571                 case MESSAGE_RELEASE: /* port releases */
2572                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) release with cause=%d location=%d (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, param->disconnectinfo.cause, param->disconnectinfo.location, e_ext.number, e_callerinfo.id);
2573                 /* portlist is release at port_disconnect_release, thanx Paul */
2574                 port_disconnect_release(portlist, message_type, param);
2575                 break;
2576
2577                 /* PORT sends a TIMEOUT message */
2578                 case MESSAGE_TIMEOUT:
2579                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received timeout (state=%d).\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id, param->state);
2580                 port_timeout(portlist, message_type, param);
2581                 break; /* release */
2582
2583                 /* PORT sends a NOTIFY message */
2584                 case MESSAGE_NOTIFY:
2585                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received notify.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
2586                 port_notify(portlist, message_type, param);
2587                 break;
2588
2589                 /* PORT sends a PROGRESS message */
2590                 case MESSAGE_PROGRESS:
2591                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received progress.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
2592                 port_progress(portlist, message_type, param);
2593                 break;
2594
2595                 /* PORT sends a SUSPEND message */
2596                 case MESSAGE_SUSPEND:
2597                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received suspend.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
2598                 port_suspend(portlist, message_type, param);
2599                 break; /* suspend */
2600
2601                 /* PORT sends a RESUME message */
2602                 case MESSAGE_RESUME:
2603                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received resume.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
2604                 port_resume(portlist, message_type, param);
2605                 break;
2606
2607 #if 0
2608                 kann nach dem test gelöscht werden, da eine direkte funktion im join und im mISDN zum austausch der message existiert
2609                 /* port assigns bchannel */
2610                 case MESSAGE_BCHANNEL: /* bchannel assignment messafe */
2611                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received bchannel message %d from port.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id, param->bchannel.type);
2612                 /* only one port is expected to be connected to bchannel */
2613                 message = message_forward(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, param);
2614                 logmessage(message->type, &message->param, portlist->port_id, DIRECTION_IN);
2615                 break;
2616 #endif
2617
2618                 /* PORT requests DTMF */
2619                 case MESSAGE_ENABLEKEYPAD:
2620                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') requests DTMF/KEYPAD.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
2621                 port_enablekeypad(portlist, message_type, param);
2622                 break;
2623
2624                 case MESSAGE_DISABLE_DEJITTER:
2625                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming disable dejitter message (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
2626                 port_disable_dejitter(portlist, message_type, param);
2627                 break;
2628
2629
2630                 default:
2631                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received a wrong message: %d\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id, message_type);
2632         }
2633
2634         /* Note: this endpoint may be destroyed, so we MUST return */
2635 }
2636
2637
2638 /* messages from join
2639  */
2640 /* join MESSAGE_CRYPT */
2641 void EndpointAppPBX::join_crypt(struct port_list *portlist, int message_type, union parameter *param)
2642 {
2643 #ifdef WITH_CRYPT
2644         switch(param->crypt.type) {
2645                 /* message from remote port to "crypt manager" */
2646                 case CU_ACTK_REQ:           /* activate key-exchange */
2647                 case CU_ACTS_REQ:            /* activate shared key */
2648                 case CU_DACT_REQ:          /* deactivate */
2649                 case CU_INFO_REQ:         /* request last info message */
2650                 cryptman_message(param->crypt.type, param->crypt.data, param->crypt.len);
2651                 break;
2652
2653                 /* message from "crypt manager" to user */
2654                 case CU_ACTK_CONF:          /* key-echange done */
2655                 case CU_ACTS_CONF:          /* shared key done */
2656                 case CU_DACT_CONF:           /* deactivated */
2657                 case CU_DACT_IND:           /* deactivated */
2658                 case CU_ERROR_IND:         /* receive error message */
2659                 case CU_INFO_IND:         /* receive info message */
2660                 case CU_INFO_CONF:         /* receive info message */
2661                 encrypt_result(param->crypt.type, (char *)param->crypt.data);
2662                 break;
2663
2664                 default:
2665                 PERROR("EPOINT(%d) epoint with terminal '%s' (caller id '%s') unknown crypt message: '%d'\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id, param->crypt.type);
2666         }
2667 #endif
2668 }
2669
2670 /* join MESSAGE_INFORMATION */
2671 void EndpointAppPBX::join_information(struct port_list *portlist, int message_type, union parameter *param)
2672 {
2673         struct lcr_msg *message;
2674
2675         e_overlap = 1;
2676
2677         while(portlist) {
2678                 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_INFORMATION);
2679                 memcpy(&message->param.information, &param->information, sizeof(struct dialing_info));
2680                 message_put(message);
2681                 logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
2682                 portlist = portlist->next;
2683         }
2684 }
2685
2686 /* join MESSAGE_FACILITY */
2687 void EndpointAppPBX::join_facility(struct port_list *portlist, int message_type, union parameter *param)
2688 {
2689         struct lcr_msg *message;
2690
2691         if (!e_ext.facility && e_ext.number[0]) {
2692                 return;
2693         }
2694
2695         while(portlist) {
2696                 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_FACILITY);
2697                 memcpy(&message->param.facilityinfo, &param->facilityinfo, sizeof(struct facility_info));
2698                 message_put(message);
2699                 logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
2700                 portlist = portlist->next;
2701         }
2702 }
2703
2704 /* join MESSAGE_MORE */
2705 void EndpointAppPBX::join_overlap(struct port_list *portlist, int message_type, union parameter *param)
2706 {
2707         struct lcr_msg *message;
2708
2709         new_state(EPOINT_STATE_IN_OVERLAP);
2710         
2711         /* own dialtone */
2712         if (e_join_pattern && e_ext.own_setup) {
2713                 /* disconnect audio */
2714                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
2715                 message->param.audiopath = 0;
2716                 message_put(message);
2717         }
2718         if (e_action) if (e_action->index == ACTION_OUTDIAL || e_action->index == ACTION_EXTERNAL) {
2719                         if (e_dialinginfo.id[0])
2720                                 set_tone(portlist, "dialing");
2721                         else
2722                                 set_tone(portlist, "dialtone");
2723                         return;
2724         }
2725         if (e_dialinginfo.id[0]) {
2726                 set_tone(portlist, "dialing");
2727         } else {
2728                 if (e_ext.number[0])
2729                         set_tone(portlist, "dialpbx");
2730                 else
2731                         set_tone(portlist, "dialtone");
2732         }
2733 }
2734
2735 /* join MESSAGE_PROCEEDING */
2736 void EndpointAppPBX::join_proceeding(struct port_list *portlist, int message_type, union parameter *param)
2737 {
2738         struct lcr_msg *message;
2739
2740         new_state(EPOINT_STATE_IN_PROCEEDING);
2741
2742         /* own proceeding tone */
2743         if (e_join_pattern) {
2744                 /* connect / disconnect audio */
2745                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
2746                 if (e_ext.own_proceeding)
2747                         message->param.audiopath = 0;
2748                 else
2749                         message->param.audiopath = 1;
2750                 message_put(message);
2751         }
2752 //                      UCPY(e_join_tone, "proceeding");
2753         if (portlist) {
2754                 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
2755                 message_put(message);
2756                 logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
2757         }
2758         set_tone(portlist, "proceeding");
2759 }
2760
2761 /* join MESSAGE_ALERTING */
2762 void EndpointAppPBX::join_alerting(struct port_list *portlist, int message_type, union parameter *param)
2763 {
2764         struct lcr_msg *message;
2765
2766         new_state(EPOINT_STATE_IN_ALERTING);
2767
2768         /* own alerting tone */
2769         if (e_join_pattern) {
2770                 /* connect / disconnect audio */
2771                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
2772                 if (e_ext.own_alerting)
2773                         message->param.audiopath = 0;
2774                 else
2775                         message->param.audiopath = 1;
2776                 message_put(message);
2777         }
2778         if (portlist) {
2779                 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_ALERTING);
2780                 message_put(message);
2781                 logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
2782         }
2783         if (e_action) if (e_action->index == ACTION_OUTDIAL || e_action->index == ACTION_EXTERNAL) {
2784                 set_tone(portlist, "ringing");
2785                 return;
2786         }
2787         if (e_ext.number[0])
2788                 set_tone(portlist, "ringpbx");
2789         else
2790                 set_tone(portlist, "ringing");
2791
2792         if (e_ext.number[0])
2793                 e_dtmf = 1; /* allow dtmf */
2794 }
2795
2796 /* join MESSAGE_CONNECT */
2797 void EndpointAppPBX::join_connect(struct port_list *portlist, int message_type, union parameter *param)
2798 {
2799         struct lcr_msg *message;
2800         time_t now;
2801
2802         new_state(EPOINT_STATE_CONNECT);
2803 //                      UCPY(e_join_tone, "");
2804 //                      
2805         if (e_ext.number[0])
2806                 e_dtmf = 1; /* allow dtmf */
2807
2808         e_powerdial_on = 0;
2809         unsched_timer(&e_powerdial_timeout);
2810         memcpy(&e_connectinfo, &param->connectinfo, sizeof(e_callerinfo));
2811         if(portlist) {
2812                 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
2813                 memcpy(&message->param, param, sizeof(union parameter));
2814
2815                 /* screen clip if prefix is required */
2816                 if (e_ext.number[0] && message->param.connectinfo.id[0] && e_ext.clip_prefix[0]) {
2817                         SCPY(message->param.connectinfo.id, e_ext.clip_prefix);
2818                         SCAT(message->param.connectinfo.id, numberrize_callerinfo(e_connectinfo.id,e_connectinfo.ntype, options.national, options.international));
2819                         message->param.connectinfo.ntype = INFO_NTYPE_UNKNOWN;
2820                 }
2821
2822                 /* use internal caller id */
2823                 if (e_ext.number[0] && e_connectinfo.extension[0] && (message->param.connectinfo.present!=INFO_PRESENT_RESTRICTED || e_ext.anon_ignore)) {
2824                         SCPY(message->param.connectinfo.id, e_connectinfo.extension);
2825                         message->param.connectinfo.ntype = INFO_NTYPE_UNKNOWN;
2826                 }
2827
2828                 /* handle restricted caller ids */
2829                 apply_callerid_restriction(&e_ext, message->param.connectinfo.id, &message->param.connectinfo.ntype, &message->param.connectinfo.present, &message->param.connectinfo.screen, message->param.connectinfo.extension, message->param.connectinfo.name);
2830                 /* display callerid if desired for extension */
2831                 SCPY(message->param.connectinfo.display, apply_callerid_display(message->param.connectinfo.id, message->param.connectinfo.itype, message->param.connectinfo.ntype, message->param.connectinfo.present, message->param.connectinfo.screen, message->param.connectinfo.extension, message->param.connectinfo.name));
2832
2833                 /* use conp, if enabld */
2834 //              if (!e_ext.centrex)
2835 //                      message->param.connectinfo.name[0] = '\0';
2836
2837                 /* send connect */
2838                 message_put(message);
2839                 logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
2840         }
2841         set_tone(portlist, NULL);
2842         e_join_pattern = 0;
2843         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
2844         message->param.audiopath = 1;
2845         message_put(message);
2846         time(&now);
2847         e_start = now;
2848 }
2849
2850 /* join MESSAGE_DISCONNECT MESSAGE_RELEASE */
2851 void EndpointAppPBX::join_disconnect_release(int message_type, union parameter *param)
2852 {
2853         char cause[16];
2854         struct lcr_msg *message;
2855         struct port_list *portlist = NULL;
2856         time_t now;
2857
2858
2859         /* be sure that we are active */
2860         notify_active();
2861         e_tx_state = NOTIFY_STATE_ACTIVE;
2862
2863         /* we are powerdialing, if e_powerdial_on is set and limit is not exceeded if given */
2864         if (e_powerdial_on && ((e_powercount+1)<e_powerlimit || e_powerlimit<1)) {
2865                 release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL,0 ); /* RELEASE_TYPE, join, port */
2866
2867                 /* set time for power dialing */
2868                 schedule_timer(&e_powerdial_timeout, (int)e_powerdelay, 0); /* set redial in the future */
2869                 e_powercount++;
2870
2871                 /* set redial tone */
2872                 if (ea_endpoint->ep_portlist) {
2873                         e_join_pattern = 0;
2874                 }
2875                 set_tone(ea_endpoint->ep_portlist, "redial");
2876                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') redialing in %d seconds\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id, (int)e_powerdelay);
2877                 /* send proceeding when powerdialing and still setup (avoid dialing timeout) */
2878                 if (e_state==EPOINT_STATE_IN_OVERLAP) {
2879                         new_state(EPOINT_STATE_IN_PROCEEDING);
2880                         if (ea_endpoint->ep_portlist) {
2881                                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
2882                                 message_put(message);
2883                                 logmessage(message->type, &message->param, ea_endpoint->ep_portlist->port_id, DIRECTION_OUT);
2884                         }
2885 /* caused the error, that the first knock sound was not there */
2886 /*                                      set_tone(portlist, "proceeding"); */
2887                 }
2888                 /* send display of powerdialing */
2889                 if (e_ext.display_dialing) {
2890                         portlist = ea_endpoint->ep_portlist;
2891                         while (portlist) {
2892                                 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
2893                                 if (e_powerlimit)
2894                                         SPRINT(message->param.notifyinfo.display, "Retry %d of %d", e_powercount, e_powerlimit);
2895                                 else
2896                                         SPRINT(message->param.notifyinfo.display, "Retry %d", e_powercount);
2897                                 message_put(message);
2898                                 logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
2899                                 portlist = portlist->next;
2900                         }
2901                 }
2902                 return;
2903         }
2904
2905         /* set stop time */
2906         time(&now);
2907         e_stop = now;
2908
2909         if ((e_state!=EPOINT_STATE_CONNECT
2910           && e_state!=EPOINT_STATE_OUT_DISCONNECT
2911           && e_state!=EPOINT_STATE_IN_OVERLAP
2912           && e_state!=EPOINT_STATE_IN_PROCEEDING
2913           && e_state!=EPOINT_STATE_IN_ALERTING)
2914          || !ea_endpoint->ep_portlist) { /* or no port */
2915                 process_hangup(param->disconnectinfo.cause, param->disconnectinfo.location);
2916                 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, param->disconnectinfo.cause, 0); /* RELEASE_TYPE, join, port */
2917                 return; /* must exit here */
2918         }
2919         /* save cause */
2920         if (!e_join_cause) {
2921                 e_join_cause = param->disconnectinfo.cause;
2922                 e_join_location = param->disconnectinfo.location;
2923         }
2924
2925         /* on release we need the audio again! */
2926         if (message_type == MESSAGE_RELEASE) {
2927                 e_join_pattern = 0;
2928                 ea_endpoint->ep_join_id = 0;
2929         }
2930         /* disconnect and select tone */
2931         new_state(EPOINT_STATE_OUT_DISCONNECT);
2932         SPRINT(cause, "cause_%02x", param->disconnectinfo.cause);
2933         /* if own_cause, we must release the join */
2934         if (e_ext.own_cause /* own cause */
2935          || !e_join_pattern) { /* no patterns */
2936                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) we have own cause or we have no patterns. (own_cause=%d pattern=%d)\n", ea_endpoint->ep_serial, e_ext.own_cause, e_join_pattern);
2937                 if (message_type != MESSAGE_RELEASE)
2938                         release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYPE, join, port */
2939                 e_join_pattern = 0;
2940         } else { /* else we enable audio */
2941                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
2942                 message->param.audiopath = 1;
2943                 message_put(message);
2944         }
2945         /* send disconnect message */
2946         SCPY(e_tone, cause);
2947         portlist = ea_endpoint->ep_portlist;
2948         while(portlist) {
2949                 set_tone(portlist, cause);
2950                 message_disconnect_port(portlist, param->disconnectinfo.cause, param->disconnectinfo.location, "");
2951                 portlist = portlist->next;
2952         }
2953 }
2954
2955 /* join MESSAGE_SETUP */
2956 void EndpointAppPBX::join_setup(struct port_list *portlist, int message_type, union parameter *param)
2957 {
2958         struct lcr_msg *message;
2959 //      struct interface        *interface;
2960
2961         /* if we already in setup state, we just update the dialing with new digits */
2962         if (e_state == EPOINT_STATE_OUT_SETUP
2963          || e_state == EPOINT_STATE_OUT_OVERLAP) {
2964                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) we are in setup state, so we do overlap dialing.\n", ea_endpoint->ep_serial);
2965                 /* if digits changed, what we have already dialed */
2966                 if (!!strncmp(e_dialinginfo.id,param->setup.dialinginfo.id,strlen(e_dialinginfo.id))) {
2967                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) we have dialed digits which have been changed or we have a new multidial, so we must redial.\n", ea_endpoint->ep_serial);
2968                         /* release all ports */
2969                         while((portlist = ea_endpoint->ep_portlist)) {
2970                                 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_RELEASE);
2971                                 message->param.disconnectinfo.cause = CAUSE_NORMAL; /* normal clearing */
2972                                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2973                                 message_put(message);
2974                                 logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
2975                                 ea_endpoint->free_portlist(portlist);
2976                         }
2977
2978                         /* disconnect audio */
2979                         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
2980                         message->param.audiopath = 0;
2981                         message_put(message);
2982
2983                         /* get dialing info */
2984                         memcpy(&e_callerinfo, &param->setup.callerinfo, sizeof(e_callerinfo));
2985                         memcpy(&e_dialinginfo, &param->setup.dialinginfo, sizeof(e_dialinginfo));
2986                         memcpy(&e_redirinfo, &param->setup.redirinfo, sizeof(e_redirinfo));
2987                         memcpy(&e_capainfo, &param->setup.capainfo, sizeof(e_capainfo));
2988                         new_state(EPOINT_STATE_OUT_OVERLAP);
2989
2990                         /* get time */
2991                         schedule_timer(&e_redial_timeout, 1, 0);
2992                         return;
2993                 }
2994                 /* if we have a pending redial, so we just adjust the dialing number */
2995                 if (e_redial_timeout.active) {
2996                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) redial in progress, so we update the dialing number to %s.\n", ea_endpoint->ep_serial, param->setup.dialinginfo.id);
2997                         memcpy(&e_dialinginfo, &param->setup.dialinginfo, sizeof(e_dialinginfo));
2998                         return;
2999                 }
3000                 if (!ea_endpoint->ep_portlist) {
3001                         PERROR("ERROR: overlap dialing to a NULL port relation\n");
3002                 }
3003                 if (ea_endpoint->ep_portlist->next) {
3004                         PERROR("ERROR: overlap dialing to a port_list port relation\n");
3005                 }
3006                 if (e_state == EPOINT_STATE_OUT_SETUP) {
3007                         /* queue digits */
3008                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) digits '%s' are queued because we didn't receive a setup acknowledge.\n", ea_endpoint->ep_serial, param->setup.dialinginfo.id);
3009                         SCAT(e_dialing_queue, param->setup.dialinginfo.id + strlen(e_dialinginfo.id));
3010                         
3011                 } else {
3012                         /* get what we have not dialed yet */
3013                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) we have already dialed '%s', we received '%s', what's left '%s'.\n", ea_endpoint->ep_serial, e_dialinginfo.id, param->setup.dialinginfo.id, param->setup.dialinginfo.id+strlen(e_dialinginfo.id));
3014                         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_INFORMATION);
3015                         SCPY(message->param.information.id, param->setup.dialinginfo.id + strlen(e_dialinginfo.id));
3016                         message->param.information.ntype = INFO_NTYPE_UNKNOWN;
3017                         message_put(message);
3018                         logmessage(message->type, &message->param, ea_endpoint->ep_portlist->port_id, DIRECTION_OUT);
3019                 }
3020                 /* always store what we have dialed or queued */
3021                 memcpy(&e_dialinginfo, &param->setup.dialinginfo, sizeof(e_dialinginfo));
3022                 
3023                 return;
3024         }
3025         if (e_state != EPOINT_STATE_IDLE) {
3026                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in idle state.\n", ea_endpoint->ep_serial);
3027                 return;
3028         }
3029         /* if an internal extension is dialed, copy that number */
3030         if (param->setup.dialinginfo.itype==INFO_ITYPE_ISDN_EXTENSION || param->setup.dialinginfo.itype==INFO_ITYPE_VBOX)
3031                 SCPY(e_ext.number, param->setup.dialinginfo.id);
3032         /* if an internal extension is dialed, get extension's info about caller */
3033         if (e_ext.number[0]) {
3034                 if (!read_extension(&e_ext, e_ext.number)) {
3035                         e_ext.number[0] = '\0';
3036                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) the called terminal='%s' is not found in directory tree!\n", ea_endpoint->ep_serial, e_ext.number);
3037                 }
3038         }
3039
3040         memcpy(&e_callerinfo, &param->setup.callerinfo, sizeof(e_callerinfo));
3041         memcpy(&e_dialinginfo, &param->setup.dialinginfo, sizeof(e_dialinginfo));
3042         memcpy(&e_redirinfo, &param->setup.redirinfo, sizeof(e_redirinfo));
3043         memcpy(&e_capainfo, &param->setup.capainfo, sizeof(e_capainfo));
3044         memcpy(&e_rtpinfo, &param->setup.rtpinfo, sizeof(e_rtpinfo));
3045
3046         /* process (voice over) data calls */
3047         if (e_ext.datacall && e_capainfo.bearer_capa!=INFO_BC_SPEECH && e_capainfo.bearer_capa!=INFO_BC_AUDIO) {
3048                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) handling data call as audio call: '%s'\n", ea_endpoint->ep_serial, e_ext.number);
3049                 memset(&e_capainfo, 0, sizeof(e_capainfo));
3050                 e_capainfo.bearer_capa = INFO_BC_AUDIO;
3051                 e_capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
3052                 e_capainfo.bearer_info1 = (options.law=='u')?INFO_INFO1_ULAW:INFO_INFO1_ALAW;
3053         }
3054
3055         new_state(EPOINT_STATE_OUT_SETUP);
3056         /* call special setup routine */