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