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