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