1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** The EndpointAppPBX implements PBX4Linux **
10 \*****************************************************************************/
15 #include <sys/types.h>
24 class EndpointAppPBX *apppbx_first = NULL;
27 * EndpointAppPBX constructor
29 EndpointAppPBX::EndpointAppPBX(class Endpoint *epoint) : EndpointApp(epoint)
31 class EndpointAppPBX **apppointer;
33 /* add application to chain */
35 apppointer = &apppbx_first;
37 apppointer = &((*apppointer)->next);
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;
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));
54 e_ruleset = ruleset_main;
56 e_rule = e_ruleset->rule_first;
61 e_match_to_action = NULL;
63 e_extdialing = e_dialinginfo.number;
67 // e_call_tone[0] = e_hold_tone[0] = '\0';
68 e_call_pattern /*= e_hold_pattern*/ = 0;
71 e_adminid = 0; // will be set, if call was initiated via admin socket
76 e_cbdialing[0] = '\0';
79 memset(&e_callbackinfo, 0, sizeof(struct caller_info));
86 e_password_timeout = 0;
87 e_multipoint_cause = CAUSE_NOUSER;
88 e_multipoint_location = LOCATION_PRIVATE_LOCAL;
89 e_dialing_queue[0] = '\0';
91 e_crypt_state = CM_ST_NULL;
92 e_crypt_keyengine_busy = 0;
93 e_crypt_info[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
111 * EpointAppPBX destructor
113 EndpointAppPBX::~EndpointAppPBX(void)
115 class EndpointAppPBX *temp, **tempp;
119 tempp = &apppbx_first;
130 PERROR("error: endpoint not in endpoint's list, exitting.\n");
140 /* set new endpoint state
142 void EndpointAppPBX::new_state(int state)
144 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) new state %s --> %s\n", ea_endpoint->ep_serial, state_name[e_state], state_name[state]);
149 /* release call and port (as specified)
151 void EndpointAppPBX::release(int release, int calllocation, int callcause, int portlocation, int portcause)
153 struct port_list *portlist;
154 struct message *message;
158 /* message to test call */
159 admin_call_response(e_adminid, ADMIN_CALL_RELEASE, "", callcause, calllocation, 0);
161 /* if a release is pending */
162 if (release==RELEASE_CALL || release==RELEASE_ALL || release==RELEASE_PORT_CALLONLY)
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)
167 call = find_call_id(ea_endpoint->ep_call_id);
169 call->release(ea_endpoint->ep_serial, 0, calllocation, callcause);
171 ea_endpoint->ep_call_id = 0;
174 if (release != RELEASE_PORT_CALLONLY)
177 call_release(e_hold_id, ea_endpoint->ep_serial, 1, calllocation, callcause);
182 if (release==RELEASE_ALL || release==RELEASE_PORT_CALLONLY)
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))
187 if (portlist->port_id)
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);
197 ea_endpoint->free_portlist(portlist);
200 /* if callback is enabled, call back with the given caller id */
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;
210 e_rule = e_ruleset->rule_first;
212 e_action_timeout = 0;
214 e_match_to_action = NULL;
216 e_extdialing = e_dialinginfo.number;
223 e_multipoint_cause = CAUSE_NOUSER;
224 e_multipoint_location = LOCATION_PRIVATE_LOCAL;
225 e_dialing_queue[0] = '\0';
227 e_crypt_state = CM_ST_NULL;
228 e_crypt_keyengine_busy = 0;
229 e_crypt_info[0] = '\0';
233 e_tx_state = NOTIFY_STATE_ACTIVE;
234 e_rx_state = NOTIFY_STATE_ACTIVE;
235 e_call_cause = e_call_location = 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])
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;
253 SCPY(e_dialinginfo.number, e_cbto);
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));
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);
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 */
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)
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");
278 /* caller id is not restricted, so we do nothing */
279 if (*present != INFO_PRESENT_RESTRICTED)
282 /* only extensions are restricted */
288 /* if we enabled anonymouse ignore */
292 /* else we remove the caller id */
296 *ntype = INFO_NTYPE_UNKNOWN;
298 // *screen = INFO_SCREEN_USER;
299 // maybe we should not make voip address anonymous
302 // maybe it's no fraud to present internal id
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)
312 static char display[81];
315 char *cid = numberrize_callerinfo(id, ntype);
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");
328 /* NOTE: is caller is is not available for this extesion, it has been removed by apply_callerid_restriction already */
330 /* internal extension's caller id */
331 if (intern[0] && e_ext.display_int)
334 SCAT(display, intern);
337 if (itype == INFO_ITYPE_VBOX)
338 SCAT(display, "(vbox)");
340 SCAT(display, "(int)");
343 /* external caller id */
344 if (!intern[0] && !voip[0] && e_ext.display_ext)
350 if (present == INFO_PRESENT_RESTRICTED)
351 SCAT(display, "anonymous");
353 SCAT(display, "unknown");
361 if (voip[0] && e_ext.display_voip)
363 if (!display[0] && cid[0])
370 /* display if callerid is anonymouse but available due anon-ignore */
371 if (e_ext.display_anon && present==INFO_PRESENT_RESTRICTED)
374 SCAT(display, "unknown");
377 SCAT(display, " anon");
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)
387 if (present == INFO_PRESENT_RESTRICTED)
388 SCAT(display, "anonymous");
390 SCAT(display, "unknown");
395 SCAT(display, " fake");
399 if (name[0] && e_ext.display_name)
401 if (!display[0] && cid[0])
412 * uses the current state to notify activity
414 void EndpointAppPBX::notify_active(void)
416 struct port_list *portlist = ea_endpoint->ep_portlist;
417 struct message *message;
422 case NOTIFY_STATE_ACTIVE:
423 /* we are already active, so we don't do anything */
426 case NOTIFY_STATE_SUSPEND:
427 notify = INFO_NOTIFY_USER_RESUMED;
430 set_tone(portlist, NULL);
431 portlist = portlist->next;
433 portlist = ea_endpoint->ep_portlist;
436 case NOTIFY_STATE_HOLD:
437 notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
440 set_tone(portlist, NULL);
441 portlist = portlist->next;
443 portlist = ea_endpoint->ep_portlist;
446 case NOTIFY_STATE_CONFERENCE:
447 notify = INFO_NOTIFY_CONFERENCE_DISCONNECTED;
450 set_tone(portlist, NULL);
451 portlist = portlist->next;
453 portlist = ea_endpoint->ep_portlist;
457 PERROR("unknown e_tx_state = %d\n", e_tx_state);
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);
467 portlist = portlist->next;
473 * keypad functions during call. one example to use this is to put a call on hold or start a conference
475 void EndpointAppPBX::keypad_function(char digit)
478 /* we must be in a call, in order to send messages to the call */
479 if (e_terminal[0] == '\0')
481 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) IGNORING keypad received not from extension.\n", ea_endpoint->ep_serial);
487 /* join conference */
489 if (ea_endpoint->ep_call_id == 0)
491 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) keypad received during connect but not during a call.\n", ea_endpoint->ep_serial);
494 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) join call with call on hold\n", ea_endpoint->ep_serial);
500 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) shared key encryption selected.\n", ea_endpoint->ep_serial);
504 /* crypt key-exchange */
506 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) key exchange encryption selected.\n", ea_endpoint->ep_serial);
512 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption off selected.\n", ea_endpoint->ep_serial);
517 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) unsupported keypad digit '%c'.\n", ea_endpoint->ep_serial, digit);
522 /* set tone pattern for port */
523 void EndpointAppPBX::set_tone(struct port_list *portlist, char *tone)
525 struct message *message;
530 /* store for suspended processes */
535 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) no endpoint to notify tone.\n", ea_endpoint->ep_serial);
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))
552 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) tone not provided since patterns are available\n", ea_endpoint->ep_serial);
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);
568 * hunts an mISDNport that is available for an outgoing call
569 * if no ifname was given, any interface that is not an extension
572 static struct mISDNport *EndpointAppPBX::hunt_port(char *ifname, int *channel)
574 struct interface *interface;
575 struct mISDNport *mISDNport;
577 interface = interface_first;
579 /* first find the given interface or, if not given, one with no extension */
584 /* check for given interface */
587 if (!strcasecmp(interface->name, ifname))
589 /* found explicit interface */
590 printlog("%3d interface %s found as given\n", ea_endpoint->ep_serial, ifname);
596 if (!interface->extension)
598 /* found non extension */
599 printlog("%3d interface %s found, that is not an extension\n", ea_endpoint->ep_serial, interface->name);
604 interface = interface->next;
607 /* see if interface has ports */
608 if (!interface->ifport)
611 printlog("%3d interface %s has no active ports, skipping.\n", ea_endpoint->ep_serial, interface->name);
612 interface = interface->next;
616 /* select port by algorithm */
617 ifport_start = interface->port;
619 if (interface->hunt == HUNT_ROUNDROBIN)
621 while(ifport_start->next && index<interface->hunt_next)
623 ifport_start = ifport_start->next;
626 printlog("%3d starting with port#%d position %d (round-robin)\n", ea_endpoint->ep_serial, ifport_start->portnum, index);
630 ifport = ifport_start;
633 /* see if port is available */
634 if (!ifport->mISDNport)
636 printlog("%3d port#%d position %d is not available, skipping.\n", ea_endpoint->ep_serial, ifport->portnum, index);
639 mISDNport = ifport->mISDNport;
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 */
646 printlog("%3d port#%d position %d is administratively blocked, skipping.\n", ea_endpoint->ep_serial, ifport->portnum, index);
650 /* see if link is up */
651 if (mISDNport->ptp && !mISDNport->l2link)
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);
658 /* check for channel form selection list */
660 selchannel = ifport->selchannel;
663 switch(selchannel->channel)
665 case CHANNEL_FREE: /* free channel */
666 if (mISDNport->b_inuse >= mISDNport->b_num)
667 break; /* all channel in use or reserverd */
670 while(i < mISDNport->b_num)
672 if (mISDNport->b_port[i] == NULL)
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);
682 case CHANNEL_ANY: /* don't ask for channel */
683 if (mISDNport->b_inuse >= mISDNport->b_num)
685 break; /* all channel in use or reserverd */
687 printlog("%3d port#%d position %d using with 'any channel'\n", ea_endpoint->ep_serial, ifport->portnum, index);
688 *channel = SEL_CHANNEL_ANY;
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;
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)
704 *channel = selchannel->channel;
705 printlog("%3d port#%d position %d selecting given channel %d\n", ea_endpoint->ep_serial, ifport->portnum, index, *channel);
711 break; /* found channel */
712 selchannel = selchannel->next;
715 /* if channel was found, return mISDNport and channel */
718 /* setting next port to start next time */
719 if (interface->hunt == HUNT_ROUNDROBIN)
724 interface->hunt_next = index;
730 printlog("%3d port#%d position %d skipping, because no channel found.\n", ea_endpoint->ep_serial, ifport->portnum, index);
733 /* go next port, until all ports are checked */
735 ifport = ifport->next;
739 ifport = interface->ifport;
741 if (ifport != ifport_start)
744 return(NULL); /* no port found */
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.
751 void EndpointAppPBX::out_setup(void)
753 struct dialing_info dialinginfo;
755 // class pdss1 *pdss1;
756 struct port_list *portlist;
757 struct message *message;
759 int cause = CAUSE_RESSOURCEUNAVAIL;
762 struct mISDNport *mISDNport;
765 class EndpointAppPBX *atemp;
766 // char allowed_ports[256];
770 char ifname[sizeof(e_ext.interfaces)],
772 struct port_settings port_settings;
775 /* create settings for creating port */
776 memset(&port_settings, 0, sizeof(port_settings));
778 SCPY(port_settings.tones_dir, e_ext.tones_dir);
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;
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 */
792 /* check what dialinginfo.itype we got */
793 switch(e_dialinginfo.itype)
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)
800 atemp = apppbx_first;
804 if (!strcmp(atemp->e_terminal, e_terminal))
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 */
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))
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 */
829 if (e_dialinginfo.itype == INFO_ITYPE_VBOX)
831 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing directly to VBOX\n", ea_endpoint->ep_serial);
836 /* string from unconditional call forward (cfu) */
840 /* present to forwarded party */
841 if (e_ext.anon_ignore && e_callerinfo.id[0])
843 e_callerinfo.present = INFO_PRESENT_ALLOWED;
845 if (!!strcmp(p, "vbox") || (e_capainfo.bearer_capa==INFO_BC_AUDIO) || (e_capainfo.bearer_capa==INFO_BC_SPEECH))
849 /* string from busy call forward (cfb) */
853 class EndpointAppPBX *checkapp = apppbx_first;
856 if (checkapp != this) /* any other endpoint except our own */
858 if (!strcmp(checkapp->e_terminal, e_terminal))
860 /* present to forwarded party */
861 if (e_ext.anon_ignore && e_callerinfo.id[0])
863 e_callerinfo.present = INFO_PRESENT_ALLOWED;
865 if (!!strcmp(p, "vbox") || (e_capainfo.bearer_capa==INFO_BC_AUDIO) || (e_capainfo.bearer_capa==INFO_BC_SPEECH))
869 checkapp = checkapp->next;
873 /* string from no-response call forward (cfnr) */
877 /* when cfnr is done, out_setup() will setup the call */
880 /* present to forwarded party */
881 if (e_ext.anon_ignore && e_callerinfo.id[0])
883 e_callerinfo.present = INFO_PRESENT_ALLOWED;
887 if (!!strcmp(p, "vbox") || (e_capainfo.bearer_capa==INFO_BC_AUDIO) || (e_capainfo.bearer_capa==INFO_BC_SPEECH))
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);
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);
901 while(*p!=',' && *p!='\0')
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);
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);
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);
921 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) port '%s' failed to create\n", ea_endpoint->ep_serial, mISDNport->interface_name);
922 goto check_anycall_intern;
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);
933 PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
935 goto check_anycall_intern;
938 if (e_callerinfo.id[0] && (e_ext.centrex || e_ext.display_name))
940 dirname = parse_directory(e_callerinfo.id, e_callerinfo.ntype);
942 SCPY(e_callerinfo.name, dirname);
944 // dss1 = (class Pdss1 *)port;
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 */
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])
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;
971 /* use internal caller id */
972 if (e_callerinfo.intern[0] && (message->param.setup.callerinfo.present!=INFO_PRESENT_RESTRICTED || e_ext.anon_ignore))
974 SCPY(message->param.setup.callerinfo.id, e_callerinfo.intern);
975 message->param.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
977 message_put(message);
982 /* string from parallel call forward (cfp) */
986 if (e_ext.anon_ignore && e_callerinfo.id[0])
988 e_callerinfo.present = INFO_PRESENT_ALLOWED;
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);
1000 /* only if vbox should be dialed, and terminal is given */
1002 if (!strcmp(p, "vbox") && e_terminal[0])
1004 /* go to the end of p */
1007 /* answering vbox call */
1008 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) answering machine\n", ea_endpoint->ep_serial);
1010 if (!(port = new VBoxPort(PORT_TYPE_VBOX_OUT, &port_settings)))
1012 PERROR("EPOINT(%d) no mem for port\n", ea_endpoint->ep_serial);
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 */
1020 while(*p!=',' && *p!='\0')
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;
1032 /* check for external or given interface */
1033 if (((!e_dialinginfo.interfaces[0])&&mISDNport->iftype==IF_EXTERN) || !strcmp(mISDNport->interface_name, e_dialinginfo.interfaces))
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)
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;
1045 /* if no channel is available */
1046 if (mISDNport->multilink || !mISDNport->ntmode || mISDNport->ptp)
1050 ii = mISDNport->b_num;
1053 if (mISDNport->b_state[i])
1057 if (use >= mISDNport->b_num)
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;
1065 /* found interface */
1066 printlog("%3d endpoint INTERFACE Interface '%s' found for external call.\n", ea_endpoint->ep_serial, mISDNport->interface_name);
1069 mISDNport = mISDNport->next;
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;
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");
1086 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) no port found or created, which is idle.\n", ea_endpoint->ep_serial);
1087 goto check_anycall_intern;
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);
1097 PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
1099 goto check_anycall_intern;
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)
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;
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);
1128 check_anycall_intern:
1129 /* now we have all ports created */
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)
1136 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
1137 return; /* must exit here */
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);
1147 if (!(port = new H323Port(PORT_TYPE_H323_OUT, "H323-out", &port_settings)))
1149 PERROR("EPOINT(%d) no mem for port\n", ea_endpoint->ep_serial);
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);
1160 PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
1162 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
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);
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);
1189 if (!(port = new Psip(PORT_TYPE_SIP_OUT, 0, 0, e_dialinginfo.number)))
1191 PERROR("EPOINT(%d) no mem for port\n", ea_endpoint->ep_serial);
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);
1202 PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
1204 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
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);
1226 /* *********************** external call */
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;
1234 while(*p!=',' && *p!='\0')
1235 SCCAT(number, *p++);
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;
1245 /* check for external or given interface */
1246 if ((!e_dialinginfo.interfaces[0]&&mISDNport->iftype==IF_EXTERN) || !strcmp(mISDNport->interface_name, e_dialinginfo.interfaces))
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)
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;
1258 /* if no channel is available */
1259 if (mISDNport->multilink || !mISDNport->ntmode || mISDNport->ptp)
1263 ii = mISDNport->b_num;
1266 if (mISDNport->b_state[i])
1270 if (use >= mISDNport->b_num)
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;
1278 /* found interface */
1279 printlog("%3d endpoint INTERFACE Interface '%s' found for external call.\n", ea_endpoint->ep_serial, mISDNport->interface_name);
1282 mISDNport = mISDNport->next;
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;
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);
1295 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) no external port available\n", ea_endpoint->ep_serial);
1296 goto check_anycall_extern;
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);
1306 PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
1308 goto check_anycall_extern;
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);
1331 check_anycall_extern:
1332 /* now we have all ports created */
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)
1339 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOCHANNEL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
1340 return; /* must exit here */
1348 /* handler for endpoint
1352 int EndpointAppPBX::handler(void)
1354 if (e_crypt_state!=CM_ST_NULL)
1359 /* process answering machine (play) handling */
1362 if (e_action->index == ACTION_VBOX_PLAY)
1365 /* process action timeout */
1366 if (e_action_timeout)
1367 if (now_d >= e_action_timeout)
1369 if (e_state!=EPOINT_STATE_CONNECT)
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);
1378 return(1); /* we must exit, because our endpoint might be gone */
1380 e_action_timeout = 0;
1383 /* process action timeout */
1384 if (e_match_timeout)
1385 if (now_d >= e_match_timeout)
1388 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) we got a match timeout.\n", ea_endpoint->ep_serial);
1390 return(1); /* we must exit, because our endpoint might be gone */
1395 /* process redialing (epoint redials to port) */
1398 if (now_d >= e_redial)
1401 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) starting redial.\n", ea_endpoint->ep_serial);
1403 new_state(EPOINT_STATE_OUT_SETUP);
1404 /* call special setup routine */
1411 /* process powerdialing (epoint redials to epoint) */
1412 if (e_powerdialing > 0)
1414 if (now_d >= e_powerdialing)
1416 e_powerdialing = -1; /* leave power dialing on */
1417 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) starting redial of powerdial.\n", ea_endpoint->ep_serial);
1420 e_ruleset = ruleset_main;
1422 e_rule = e_ruleset->rule_first;
1424 new_state(EPOINT_STATE_IN_OVERLAP);
1430 /* process call forward no response */
1433 struct port_list *portlist;
1434 struct message *message;
1436 if (now >= e_cfnr_release)
1438 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call-forward-no-response time has expired, hanging up.\n", ea_endpoint->ep_serial);
1441 /* release all ports */
1442 while((portlist = ea_endpoint->ep_portlist))
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);
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);
1464 if (now >= e_cfnr_call)
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);
1472 /* handle connection to user */
1473 if (e_state == EPOINT_STATE_IDLE)
1475 /* epoint is idle, check callback */
1477 if (now_d >= e_callback)
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);
1487 /* check for password timeout */
1489 if (e_action->index==ACTION_PASSWORD || e_action->index==ACTION_PASSWORD_WRITE)
1491 struct port_list *portlist;
1493 if (now >= e_password_timeout)
1495 e_ruleset = ruleset_main;
1497 e_rule = e_ruleset->rule_first;
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;
1503 new_state(EPOINT_STATE_OUT_DISCONNECT);
1504 portlist = ea_endpoint->ep_portlist;
1507 message_disconnect_port(portlist, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, "");
1508 set_tone(portlist, "cause_10");
1518 /* doing a hookflash */
1519 void EndpointAppPBX::hookflash(void)
1523 /* be sure that we are active */
1525 e_tx_state = NOTIFY_STATE_ACTIVE;
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)
1531 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot hooflash while child process is running.\n", ea_endpoint->ep_serial);
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);
1541 port->set_echotest(0);
1543 if (ea_endpoint->ep_call_id)
1545 release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
1547 e_ruleset = ruleset_main;
1549 e_rule = e_ruleset->rule_first;
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;
1556 if (e_dialinginfo.number[0])
1558 set_tone(ea_endpoint->ep_portlist, "dialing");
1562 set_tone(ea_endpoint->ep_portlist, "dialpbx");
1569 /* messages from port
1571 /* port MESSAGE_SETUP */
1572 void EndpointAppPBX::port_setup(struct port_list *portlist, int message_type, union parameter *param)
1574 struct message *message;
1576 struct interface *interface;
1578 char extension1[32];
1580 int writeext; /* flags need to write extension after modification */
1583 portlist->port_type = param->setup.port_type;
1584 memcpy(&e_callerinfo, ¶m->setup.callerinfo, sizeof(e_callerinfo));
1585 memcpy(&e_dialinginfo, ¶m->setup.dialinginfo, sizeof(e_dialinginfo));
1586 memcpy(&e_redirinfo, ¶m->setup.redirinfo, sizeof(e_redirinfo));
1587 memcpy(&e_capainfo, ¶m->setup.capainfo, sizeof(e_capainfo));
1588 e_dtmf = param->setup.dtmf;
1590 /* check where the call is from */
1591 if (e_callerinfo.interface[0])
1593 interface = interface_first;
1596 if (!strcmp(e_callerinfo.interface, interface->name))
1600 interface = interface->next;
1604 /* check for MSN numbers, use first MSN if no match */
1606 ifmsn = interface->ifmsn;
1611 if (!strcmp(ifmns->mns, e_callerinfo.id))
1615 ifmsn = ifmsn->next;
1617 if (!ifmns && mns1) // not in list, first msn given
1618 SCPY(p_callerinfo.id, msn1);
1620 /* interface is known */
1621 if (interface->iftype==IF_INTERN)
1624 /* interface is internal */
1625 if (interface->extensions[0])
1628 /* extensions are assigned to interface */
1629 p = interface->extensions;
1630 extension1[0] = '\0';
1633 extension[0] = '\0';
1634 while(*p!=',' && *p!='\0')
1635 SCCAT(extension, *p++);
1639 SCPY(extension1, extension);
1640 if (!strcmp(extension, e_callerinfo.id))
1642 extension[0] = '\0'; /* NOTE: empty if we did not find */
1646 /* id was found at extension's list */
1647 e_callerinfo.itype = INFO_ITYPE_INTERN;
1648 SCPY(e_callerinfo.intern, extension);
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);
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);
1665 /* interface is external */
1666 e_callerinfo.intern[0] = '\0';
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 */
1679 if (e_callerinfo.itype == INFO_ITYPE_INTERN)
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);
1688 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming call is external or voip\n", ea_endpoint->ep_serial);
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='":"",
1697 (e_redirinfo.id[0])?"'":"",
1698 e_dialinginfo.number
1701 if (e_callerinfo.itype == INFO_ITYPE_INTERN)
1703 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call from extension '%s'\n", ea_endpoint->ep_serial, e_terminal);
1705 /* get extension's info about caller */
1706 if (!read_extension(&e_ext, e_terminal))
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 */
1719 /* put prefix (next) in front of e_dialinginfo.number */
1722 SPRINT(buffer, "%s%s", e_ext.next, e_dialinginfo.number);
1723 SCPY(e_dialinginfo.number, buffer);
1724 e_ext.next[0] = '\0';
1726 } else if (e_ext.prefix[0])
1728 SPRINT(buffer, "%s%s", e_ext.prefix, e_dialinginfo.number);
1729 SCPY(e_dialinginfo.number, buffer);
1732 /* screen caller id */
1733 e_callerinfo.screen = INFO_SCREEN_NETWORK;
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)
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;
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;
1757 /* extension is written */
1759 write_extension(&e_ext, e_terminal);
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)
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);
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))
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);
1780 port = find_port_id(portlist->port_id);
1782 port->open_record(e_ext.record, 0, 0, e_terminal, e_ext.anon_ignore, "", 0);
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 */
1796 e_ruleset = ruleset_main;
1798 e_rule = e_ruleset->rule_first;
1800 e_extdialing = e_dialinginfo.number;
1801 new_state(EPOINT_STATE_IN_SETUP);
1802 if (e_dialinginfo.number[0])
1804 set_tone(portlist, "dialing");
1808 set_tone(portlist, "dialpbx");
1810 set_tone(portlist, "dialtone");
1813 if (e_state == EPOINT_STATE_IN_SETUP)
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);
1823 /* port MESSAGE_INFORMATION */
1824 void EndpointAppPBX::port_information(struct port_list *portlist, int message_type, union parameter *param)
1826 printlog("%3d incoming INFORMATION information='%s'\n",
1827 ea_endpoint->ep_serial,
1828 param->information.number
1832 /* turn off dtmf detection, in case dtmf is sent with keypad information */
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);
1839 /* if vbox_play is done, the information are just used as they come */
1841 if (e_action->index == ACTION_VBOX_PLAY)
1843 /* concat dialing string */
1844 SCAT(e_dialinginfo.number, param->information.number);
1849 /* keypad when disconnect but in connected mode */
1850 if (e_state==EPOINT_STATE_OUT_DISCONNECT && e_connectedmode)
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')
1861 /* keypad when connected */
1862 if (e_state == EPOINT_STATE_CONNECT && e_ext.keypad)
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')
1870 if (param->information.number[0])
1871 keypad_function(param->information.number[0]);
1874 if (e_state != EPOINT_STATE_IN_OVERLAP)
1876 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in overlap, or connect state.\n", ea_endpoint->ep_serial);
1879 if (!param->information.number[0])
1881 if (e_dialinginfo.number[0]=='\0' && !e_action)
1883 set_tone(portlist, "dialing");
1886 if (e_action->index==ACTION_OUTDIAL
1887 || e_action->index==ACTION_EXTERNAL)
1890 set_tone(portlist, "dialing");
1891 else if (!e_extdialing[0])
1892 set_tone(portlist, "dialing");
1894 /* concat dialing string */
1895 SCAT(e_dialinginfo.number, param->information.number);
1899 /* port MESSAGE_DTMF */
1900 void EndpointAppPBX::port_dtmf(struct port_list *portlist, int message_type, union parameter *param)
1902 printlog("%3d incoming DTMF digit='%c'\n",
1903 ea_endpoint->ep_serial,
1906 /* only if dtmf detection is enabled */
1909 PDEBUG(DEBUG_EPOINT, "dtmf detection is disabled\n");
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 */
1917 if (e_action->index == ACTION_VBOX_PLAY)
1919 /* concat dialing string */
1920 if (strlen(e_dialinginfo.number)+1 < sizeof(e_dialinginfo.number))
1922 e_dialinginfo.number[strlen(e_dialinginfo.number)+1] = '\0';
1923 e_dialinginfo.number[strlen(e_dialinginfo.number)] = param->dtmf;
1926 /* continue to process *X# sequences */
1930 /* check for *X# sequence */
1931 if (e_state == EPOINT_STATE_CONNECT)
1933 if (e_dtmf_time+3 < now)
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 */
1943 /* we have a sequence of digits, see what we got */
1944 if (param->dtmf == '*')
1946 else if (param->dtmf>='0' && param->dtmf<='9')
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 == '#')
1954 if (e_dtmf_last>='0' && e_dtmf_last<='9')
1956 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dtmf sequence *%c# detected.\n", ea_endpoint->ep_serial, e_dtmf_last);
1957 if (e_dtmf_last == '0')
1962 /* processing keypad function */
1964 keypad_function(e_dtmf_last);
1970 /* set last time of dtmf */
1975 /* check for ## hookflash during dialing */
1977 if (e_action->index==ACTION_PASSWORD
1978 || e_action->index==ACTION_PASSWORD_WRITE)
1980 if (param->dtmf=='#') /* current digit is '#' */
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, ##. */
2000 /* dialing using dtmf digit */
2001 if (e_state==EPOINT_STATE_IN_OVERLAP)// && e_state==e_connectedmode)
2003 if (e_dialinginfo.number[0]=='\0' && !e_action)
2005 set_tone(portlist, "dialing");
2007 /* concat dialing string */
2008 if (strlen(e_dialinginfo.number)+1 < sizeof(e_dialinginfo.number))
2010 e_dialinginfo.number[strlen(e_dialinginfo.number)+1] = '\0';
2011 e_dialinginfo.number[strlen(e_dialinginfo.number)] = param->dtmf;
2017 /* port MESSAGE_CRYPT */
2018 void EndpointAppPBX::port_crypt(struct port_list *portlist, int message_type, union parameter *param)
2020 /* send crypt response to cryptman */
2021 if (param->crypt.type == CR_MESSAGE_IND)
2022 cryptman_msg2man(param->crypt.data, param->crypt.len);
2024 cryptman_message(param->crypt.type, param->crypt.data, param->crypt.len);
2027 /* port MESSAGE_OVERLAP */
2028 void EndpointAppPBX::port_overlap(struct port_list *portlist, int message_type, union parameter *param)
2030 struct message *message;
2032 /* signal to call tool */
2033 admin_call_response(e_adminid, ADMIN_CALL_SETUP_ACK, "", 0, 0, 0);
2035 printlog("%3d incoming SETUP ACKNOWLEDGE\n",
2036 ea_endpoint->ep_serial
2038 if (e_dialing_queue[0] && portlist)
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';
2049 /* check if pattern is available */
2050 if (!ea_endpoint->ep_portlist->next && portlist->earlyb) /* one port_list relation and tones available */
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);
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);
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);
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);
2071 new_state(EPOINT_STATE_OUT_OVERLAP);
2072 /* if we are in a call */
2073 if (ea_endpoint->ep_call_id)
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);
2081 /* port MESSAGE_PROCEEDING */
2082 void EndpointAppPBX::port_proceeding(struct port_list *portlist, int message_type, union parameter *param)
2084 struct message *message;
2086 /* signal to call tool */
2087 admin_call_response(e_adminid, ADMIN_CALL_PROCEEDING, "", 0, 0, 0);
2089 printlog("%3d incoming PROCEEDING\n",
2090 ea_endpoint->ep_serial
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 */
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);
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);
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);
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);
2115 /* if we are in a call */
2116 if (ea_endpoint->ep_call_id)
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);
2124 /* port MESSAGE_ALERTING */
2125 void EndpointAppPBX::port_alerting(struct port_list *portlist, int message_type, union parameter *param)
2127 struct message *message;
2129 /* signal to call tool */
2130 admin_call_response(e_adminid, ADMIN_CALL_ALERTING, "", 0, 0, 0);
2132 printlog("%3d incoming ALERTING\n",
2133 ea_endpoint->ep_serial
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 */
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);
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);
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);
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);
2158 /* if we are in a call */
2159 if (ea_endpoint->ep_call_id)
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);
2167 /* port MESSAGE_CONNECT */
2168 void EndpointAppPBX::port_connect(struct port_list *portlist, int message_type, union parameter *param)
2170 struct message *message;
2172 unsigned long port_id = portlist->port_id;
2173 struct port_list *tportlist;
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);
2179 memcpy(&e_connectinfo, ¶m->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":""
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 */
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)
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");
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);
2203 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) removing all other ports (end)\n", ea_endpoint->ep_serial);
2207 /* screen connected name */
2209 SCPY(e_connectinfo.name, e_ext.name);
2211 /* add internal id to colp */
2212 SCPY(e_connectinfo.intern, e_terminal);
2214 /* we store the connected port number */
2215 SCPY(e_terminal_interface, e_connectinfo.interfaces);
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)
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;
2226 if (portlist->port_type==PORT_TYPE_VBOX_OUT)
2228 e_connectinfo.itype = INFO_ITYPE_VBOX;
2229 e_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
2232 new_state(EPOINT_STATE_CONNECT);
2234 /* set volume of rx and tx */
2235 if (e_ext.txvol!=256 || e_ext.rxvol!=256)
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);
2244 e_cfnr_call = e_cfnr_release = 0;
2246 e_dtmf = 1; /* allow dtmf */
2247 // if (call_countrelations(ea_endpoint->ep_call_id) == 2)
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)
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 */
2256 port = find_port_id(portlist->port_id);
2259 SCPY(e_connectinfo.id, nationalize_callerinfo(port->p_dialinginfo.number, &e_connectinfo.ntype));
2260 e_connectinfo.present = INFO_PRESENT_ALLOWED;
2263 if (portlist->port_type==PORT_TYPE_H323_OUT) /* h323 extension answered */
2265 SCPY(e_connectinfo.voip, port->p_dialinginfo.number);
2266 e_connectinfo.present = INFO_PRESENT_ALLOWED;
2267 // e_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
2269 if (portlist->port_type==PORT_TYPE_SIP_OUT) /* sip extension answered */
2271 SCPY(e_connectinfo.voip, port->p_dialinginfo.number);
2272 e_connectinfo.present = INFO_PRESENT_ALLOWED;
2273 // e_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
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);
2280 if (ea_endpoint->ep_call_id)
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)
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);
2293 /* get extension's info about terminal */
2294 if (!read_extension(&e_ext, e_terminal))
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 */
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;
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)
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);
2323 SCPY(e_callerinfo.id, e_ext.callerid);
2324 e_callerinfo.present = e_ext.callerid_present;
2325 e_callerinfo.ntype = e_ext.callerid_type;
2328 e_connectedmode = 1; /* dtmf-hangup & disconnect prevention */
2331 /* check if caller id is NOT authenticated */
2332 if (!parse_callbackauth(e_terminal, &e_callbackinfo))
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;
2345 /* incoming call (callback) */
2346 e_ruleset = ruleset_main;
2348 e_rule = e_ruleset->rule_first;
2350 e_extdialing = e_dialinginfo.number;
2351 if (e_dialinginfo.number[0])
2353 set_tone(portlist, "dialing");
2357 set_tone(portlist, "dialpbx");
2360 } else /* testcall */
2362 set_tone(portlist, "hold");
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))
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);
2373 port = find_port_id(portlist->port_id);
2375 port->open_record(e_ext.record, 0, 0, e_terminal, e_ext.anon_ignore, "", 0);
2380 /* port MESSAGE_DISCONNECT MESSAGE_RELEASE */
2381 void EndpointAppPBX::port_disconnect_release(struct port_list *portlist, int message_type, union parameter *param)
2383 struct message *message;
2385 unsigned long port_id = portlist->port_id;
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);
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:"-"
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)
2404 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are already disconnected.\n", ea_endpoint->ep_serial);
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 */
2412 e_multipoint_cause = CAUSE_REJECTED;
2413 e_multipoint_location = param->disconnectinfo.location;
2415 if (param->disconnectinfo.cause==CAUSE_NORMAL && e_multipoint_cause!=CAUSE_REJECTED) /* reject via hangup */
2417 e_multipoint_cause = CAUSE_NORMAL;
2418 e_multipoint_location = param->disconnectinfo.location;
2420 if (param->disconnectinfo.cause==CAUSE_BUSY && e_multipoint_cause!=CAUSE_REJECTED && e_multipoint_cause!=CAUSE_NORMAL) /* busy */
2422 e_multipoint_cause = CAUSE_BUSY;
2423 e_multipoint_location = param->disconnectinfo.location;
2425 if (param->disconnectinfo.cause==CAUSE_OUTOFORDER && e_multipoint_cause!=CAUSE_BUSY && e_multipoint_cause!=CAUSE_REJECTED && e_multipoint_cause!=CAUSE_NORMAL) /* no L1 */
2427 e_multipoint_cause = CAUSE_OUTOFORDER;
2428 e_multipoint_location = param->disconnectinfo.location;
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 */
2432 e_multipoint_cause = param->disconnectinfo.cause;
2433 e_multipoint_location = param->disconnectinfo.location;
2435 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) new multipoint cause %d location %d.\n", ea_endpoint->ep_serial, e_multipoint_cause, e_multipoint_location);
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)
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;
2444 if (portlist->port_id == port_id)
2446 portlist = portlist->next;
2450 PERROR("EPOINT(%d) software error: no portlist related to the calling port.\n", ea_endpoint->ep_serial);
2453 if (message_type != MESSAGE_RELEASE)
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);
2461 ea_endpoint->free_portlist(portlist);
2462 return; /* one relation removed */
2464 if (e_multipoint_cause)
2466 cause = e_multipoint_cause;
2467 location = e_multipoint_location;
2470 cause = param->disconnectinfo.cause;
2471 location = param->disconnectinfo.location;
2474 e_cfnr_call = e_cfnr_release = 0;
2476 /* process hangup */
2477 process_hangup(e_call_cause, e_call_location);
2478 e_multipoint_cause = 0;
2479 e_multipoint_location = LOCATION_PRIVATE_LOCAL;
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);
2486 new_state(EPOINT_STATE_IN_DISCONNECT);
2487 if (ea_endpoint->ep_call_id)
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
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);
2514 cryptman_message(CI_DISCONNECT_IND, NULL, 0);
2518 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) the port has no patterns.\n", ea_endpoint->ep_serial);
2521 release(RELEASE_ALL, location, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, callcause, portcause */
2522 return; /* must exit here */
2525 /* port MESSAGE_TIMEOUT */
2526 void EndpointAppPBX::port_timeout(struct port_list *portlist, int message_type, union parameter *param)
2530 printlog("%3d incoming TIMEOUT\n",
2531 ea_endpoint->ep_serial
2533 message_type = MESSAGE_DISCONNECT;
2534 switch (param->state)
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 */
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;
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 */
2554 case PORT_STATE_IN_PROCEEDING:
2555 param->disconnectinfo.cause = CAUSE_NOUSER;
2556 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL; /* no user responding */
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 */
2565 case PORT_STATE_IN_ALERTING:
2566 param->disconnectinfo.cause = CAUSE_NOANSWER;
2567 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
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 */
2577 param->disconnectinfo.cause = 31; /* normal unspecified */
2578 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2580 /* release call, disconnect isdn */
2582 new_state(EPOINT_STATE_OUT_DISCONNECT);
2583 SPRINT(cause, "cause_%02x", param->disconnectinfo.cause);
2584 SCPY(e_tone, cause);
2587 set_tone(portlist, cause);
2588 message_disconnect_port(portlist, param->disconnectinfo.cause, param->disconnectinfo.location, "");
2589 portlist = portlist->next;
2591 release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
2594 /* port MESSAGE_NOTIFY */
2595 void EndpointAppPBX::port_notify(struct port_list *portlist, int message_type, union parameter *param)
2597 struct message *message;
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)
2605 e_rx_state = track_notify(e_rx_state, param->notifyinfo.notify);
2608 /* if we get notification from stack, local shows if we disabled/enabled audio stream */
2609 if (param->notifyinfo.local) switch(param->notifyinfo.notify)
2611 case INFO_NOTIFY_REMOTE_HOLD:
2612 case INFO_NOTIFY_USER_SUSPENDED:
2613 /* tell call about it */
2614 if (ea_endpoint->ep_call_id)
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);
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)
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);
2635 /* set current tone */
2637 set_tone(portlist, e_tone);
2638 /* tell call about it */
2639 if (ea_endpoint->ep_call_id)
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);
2648 /* get name of notify */
2649 switch(param->notifyinfo.notify)
2655 logtext = "USER_SUSPENDED";
2658 logtext = "BEARER_SERVICE_CHANGED";
2661 logtext = "USER_RESUMED";
2664 logtext = "CONFERENCE_ESTABLISHED";
2667 logtext = "CONFERENCE_DISCONNECTED";
2670 logtext = "OTHER_PARTY_ADDED";
2673 logtext = "ISOLATED";
2676 logtext = "REATTACHED";
2679 logtext = "OTHER_PARTY_ISOLATED";
2682 logtext = "OTHER_PARTY_REATTACHED";
2685 logtext = "OTHER_PARTY_SPLIT";
2688 logtext = "OTHER_PARTY_DISCONNECTED";
2691 logtext = "CONFERENCE_FLOATING";
2694 logtext = "CONFERENCE_DISCONNECTED_PREEMTED";
2697 logtext = "CONFERENCE_FLOATING_SERVED_USER_PREEMTED";
2700 logtext = "CALL_IS_A_WAITING_CALL";
2703 logtext = "DIVERSION_ACTIVATED";
2706 logtext = "RESERVED_CT_1";
2709 logtext = "RESERVED_CT_2";
2712 logtext = "REVERSE_CHARGING";
2715 logtext = "REMOTE_HOLD";
2718 logtext = "REMOTE_RETRIEVAL";
2721 logtext = "CALL_IS_DIVERTING";
2724 SPRINT(buffer, "indicator=%d", param->notifyinfo.notify - 0x80);
2728 printlog("%3d incoming NOTIFY notify='%s' id='%s'%s\n",
2729 ea_endpoint->ep_serial,
2731 param->notifyinfo.id,
2732 (param->notifyinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":""
2735 /* notify call if available */
2736 if (ea_endpoint->ep_call_id)
2738 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_NOTIFY);
2739 memcpy(&message->param.notifyinfo, ¶m->notifyinfo, sizeof(struct notify_info));
2740 message_put(message);
2745 /* port MESSAGE_FACILITY */
2746 void EndpointAppPBX::port_facility(struct port_list *portlist, int message_type, union parameter *param)
2748 struct message *message;
2750 printlog("%3d incoming FACILITY len='%d'\n",
2751 ea_endpoint->ep_serial,
2752 param->facilityinfo.len
2755 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_FACILITY);
2756 memcpy(&message->param.facilityinfo, ¶m->facilityinfo, sizeof(struct facility_info));
2757 message_put(message);
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)
2764 printlog("%3d incoming SUSPEND\n",
2765 ea_endpoint->ep_serial
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;
2772 /* remove port relation */
2773 ea_endpoint->free_portlist(portlist);
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)
2780 printlog("%3d incoming RESUME\n",
2781 ea_endpoint->ep_serial
2783 /* epoint is now resumed */
2784 ea_endpoint->ep_park = 0;
2789 /* port sends message to the endpoint
2791 void EndpointAppPBX::ea_message_port(unsigned long port_id, int message_type, union parameter *param)
2793 struct port_list *portlist;
2794 struct message *message;
2797 portlist = ea_endpoint->ep_portlist;
2800 if (port_id == portlist->port_id)
2802 portlist = portlist->next;
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);
2810 // PDEBUG(DEBUG_EPOINT, "received message %d (terminal %s, caller id %s)\n", message, e_terminal, e_callerinfo.id);
2811 switch(message_type)
2813 case MESSAGE_DATA: /* data from port */
2814 /* send back to source for recording */
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);
2822 /* check if there is a call */
2823 if (!ea_endpoint->ep_call_id)
2825 /* continue if only one portlist */
2826 if (ea_endpoint->ep_portlist->next != NULL)
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);
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);
2837 if (e_action->index == ACTION_VBOX_PLAY)
2841 if (e_action->index == ACTION_EFI)
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);
2851 if (e_action->index == ACTION_VBOX_PLAY)
2853 e_vbox_counter = param->counter.current;
2854 if (param->counter.max >= 0)
2855 e_vbox_counter_max = param->counter.max;
2859 /* PORT sends SETUP message */
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)
2864 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in idle state.\n", ea_endpoint->ep_serial);
2867 port_setup(portlist, message_type, param);
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);
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);
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);
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);
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)
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);
2902 port_overlap(portlist, message_type, param);
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)
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);
2914 port_proceeding(portlist, message_type, param);
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)
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);
2927 port_alerting(portlist, message_type, param);
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)
2938 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in setup, proceeding or alerting state.\n", ea_endpoint->ep_serial);
2941 port_connect(portlist, message_type, param);
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);
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);
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 */
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);
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 */
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);
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);
2988 port = find_port_id(portlist->port_id);
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);
2992 /* the recording is done to the vbox directory rather than to the recording directory (using vbox_codec) */
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);
2999 /* Note: this endpoint may be destroyed, so we MUST return */
3003 /* messages from port
3005 /* call MESSAGE_CRYPT */
3006 void EndpointAppPBX::call_crypt(struct port_list *portlist, int message_type, union parameter *param)
3008 switch(param->crypt.type)
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);
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);
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);
3034 /* call MESSAGE_INFORMATION */
3035 void EndpointAppPBX::call_information(struct port_list *portlist, int message_type, union parameter *param)
3037 struct message *message;
3043 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_INFORMATION);
3044 memcpy(&message->param.information, ¶m->information, sizeof(struct dialing_info));
3045 message_put(message);
3046 logmessage(message);
3047 portlist = portlist->next;
3051 /* call MESSAGE_FACILITY */
3052 void EndpointAppPBX::call_facility(struct port_list *portlist, int message_type, union parameter *param)
3054 struct message *message;
3056 if (!e_ext.facility)
3063 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_FACILITY);
3064 memcpy(&message->param.facilityinfo, ¶m->facilityinfo, sizeof(struct facility_info));
3065 message_put(message);
3066 logmessage(message);
3067 portlist = portlist->next;
3071 /* call MESSAGE_MORE */
3072 void EndpointAppPBX::call_overlap(struct port_list *portlist, int message_type, union parameter *param)
3074 struct message *message;
3076 new_state(EPOINT_STATE_IN_OVERLAP);
3079 if (e_call_pattern && e_ext.own_setup)
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);
3086 if (e_action) if (e_action->index == ACTION_OUTDIAL || e_action->index == ACTION_EXTERNAL)
3088 set_tone(portlist, "dialtone");
3092 set_tone(portlist, "dialpbx");
3094 set_tone(portlist, "dialtone");
3097 /* call MESSAGE_PROCEEDING */
3098 void EndpointAppPBX::call_proceeding(struct port_list *portlist, int message_type, union parameter *param)
3100 struct message *message;
3102 new_state(EPOINT_STATE_IN_PROCEEDING);
3104 /* own proceeding tone */
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;
3112 message->param.channel = CHANNEL_STATE_CONNECT;
3113 message_put(message);
3115 // UCPY(e_call_tone, "proceeding");
3118 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
3119 message_put(message);
3120 logmessage(message);
3122 set_tone(portlist, "proceeding");
3125 /* call MESSAGE_ALERTING */
3126 void EndpointAppPBX::call_alerting(struct port_list *portlist, int message_type, union parameter *param)
3128 struct message *message;
3130 new_state(EPOINT_STATE_IN_ALERTING);
3132 /* own alerting tone */
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;
3140 message->param.channel = CHANNEL_STATE_CONNECT;
3141 message_put(message);
3145 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_ALERTING);
3146 message_put(message);
3147 logmessage(message);
3149 if (e_action) if (e_action->index == ACTION_OUTDIAL || e_action->index == ACTION_EXTERNAL)
3151 set_tone(portlist, "ringing");
3155 set_tone(portlist, "ringpbx");
3157 set_tone(portlist, "ringing");
3160 /* call MESSAGE_CONNECT */
3161 void EndpointAppPBX::call_connect(struct port_list *portlist, int message_type, union parameter *param)
3163 struct message *message;
3165 new_state(EPOINT_STATE_CONNECT);
3166 // UCPY(e_call_tone, "");
3168 e_dtmf = 1; /* allow dtmf */
3170 memcpy(&e_connectinfo, ¶m->connectinfo, sizeof(e_callerinfo));
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])
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;
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))
3185 SCPY(message->param.connectinfo.id, e_connectinfo.intern);
3186 message->param.connectinfo.ntype = INFO_NTYPE_UNKNOWN;
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 */
3194 message->param.connectinfo.name[0] = '\0';
3196 message_put(message);
3197 logmessage(message);
3199 set_tone(portlist, NULL);
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);
3207 /* call MESSAGE_DISCONNECT MESSAGE_RELEASE */
3208 void EndpointAppPBX::call_disconnect_release(struct port_list *portlist, int message_type, union parameter *param)
3211 struct message *message;
3214 /* be sure that we are active */
3216 e_tx_state = NOTIFY_STATE_ACTIVE;
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))
3221 release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
3223 /* set time for power dialing */
3224 e_powerdialing = now_d + e_powerdelay; /* set redial in the future */
3227 /* set redial tone */
3228 if (ea_endpoint->ep_portlist)
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)
3237 new_state(EPOINT_STATE_IN_PROCEEDING);
3240 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
3241 message_put(message);
3242 logmessage(message);
3244 /* caused the error, that the first knock sound was not there */
3245 /* set_tone(portlist, "proceeding"); */
3247 /* send display of powerdialing */
3248 if (e_ext.display_dialing)
3252 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
3254 SPRINT(message->param.notifyinfo.display, "Retry %d of %d", e_powercount, e_powerlimit);
3256 SPRINT(message->param.notifyinfo.display, "Retry %d", e_powercount);
3257 message_put(message);
3258 logmessage(message);
3259 portlist = portlist->next;
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 */
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 */
3282 e_call_cause = param->disconnectinfo.cause;
3283 e_call_location = param->disconnectinfo.location;
3286 /* on release we need the audio again! */
3287 if (message_type == MESSAGE_RELEASE)
3290 ea_endpoint->ep_call_id = 0;
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 */
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 */
3303 } else /* else we enable audio */
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);
3309 /* send disconnect message */
3310 SCPY(e_tone, cause);
3313 set_tone(portlist, cause);
3314 message_disconnect_port(portlist, param->disconnectinfo.cause, param->disconnectinfo.location, "");
3315 portlist = portlist->next;
3319 /* call MESSAGE_SETUP */
3320 void EndpointAppPBX::call_setup(struct port_list *portlist, int message_type, union parameter *param)
3322 struct message *message;
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)
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)))
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))
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);
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);
3349 /* get dialing info */
3350 memcpy(&e_callerinfo, ¶m->setup.callerinfo, sizeof(e_callerinfo));
3351 memcpy(&e_dialinginfo, ¶m->setup.dialinginfo, sizeof(e_dialinginfo));
3352 memcpy(&e_redirinfo, ¶m->setup.redirinfo, sizeof(e_redirinfo));
3353 memcpy(&e_capainfo, ¶m->setup.capainfo, sizeof(e_capainfo));
3354 new_state(EPOINT_STATE_OUT_OVERLAP);
3357 e_redial = now_d + 1; /* set redial one second in the future */
3360 /* if we have a pending redial, so we just adjust the dialing number */
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, ¶m->setup.dialinginfo, sizeof(e_dialinginfo));
3367 if (!ea_endpoint->ep_portlist)
3369 PERROR("ERROR: overlap dialing to a NULL port relation\n");
3371 if (ea_endpoint->ep_portlist->next)
3373 PERROR("ERROR: overlap dialing to a port_list port relation\n");
3375 if (e_state == EPOINT_STATE_OUT_SETUP)
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));
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);
3391 /* always store what we have dialed or queued */
3392 memcpy(&e_dialinginfo, ¶m->setup.dialinginfo, sizeof(e_dialinginfo));
3396 if (e_state != EPOINT_STATE_IDLE)
3398 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in idle state.\n", ea_endpoint->ep_serial);
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 */
3407 if (!read_extension(&e_ext, e_terminal))
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);
3414 memcpy(&e_callerinfo, ¶m->setup.callerinfo, sizeof(e_callerinfo));
3415 memcpy(&e_dialinginfo, ¶m->setup.dialinginfo, sizeof(e_dialinginfo));
3416 memcpy(&e_redirinfo, ¶m->setup.redirinfo, sizeof(e_redirinfo));
3417 memcpy(&e_capainfo, ¶m->setup.capainfo, sizeof(e_capainfo));
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)
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;
3429 new_state(EPOINT_STATE_OUT_SETUP);
3430 /* call special setup routine */
3434 /* call MESSAGE_mISDNSIGNAL */
3435 void EndpointAppPBX::call_mISDNsignal(struct port_list *portlist, int message_type, union parameter *param)
3437 struct message *message;
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;
3448 /* call MESSAGE_NOTIFY */
3449 void EndpointAppPBX::call_notify(struct port_list *portlist, int message_type, union parameter *param)
3451 struct message *message;
3454 if (param->notifyinfo.notify)
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)
3464 if (new_state!=NOTIFY_STATE_HOLD && new_state!=NOTIFY_STATE_SUSPEND)
3468 set_tone(portlist, "");
3469 portlist = portlist->next;
3471 portlist = ea_endpoint->ep_portlist;
3476 if (new_state==NOTIFY_STATE_HOLD || new_state==NOTIFY_STATE_SUSPEND)
3480 set_tone(portlist, "hold");
3481 portlist = portlist->next;
3483 portlist = ea_endpoint->ep_portlist;
3488 /* save new state */
3489 e_tx_state = new_state;
3492 /* notify port(s) about it */
3495 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
3496 memcpy(&message->param.notifyinfo, ¶m->notifyinfo, sizeof(struct notify_info));
3497 /* handle restricted caller ids */
3498 apply_callerid_restriction(e_ext.anon_ignore, portlist->port_type, message->param.notifyinfo.id, &message->param.notifyinfo.ntype, &message->param.notifyinfo.present, NULL, message->param.notifyinfo.voip, message->param.notifyinfo.intern, 0);
3499 /* display callerid if desired for extension */
3500 SCPY(message->param.notifyinfo.display, apply_callerid_display(message->param.notifyinfo.id, message->param.notifyinfo.itype, message->param.notifyinfo.ntype, message->param.notifyinfo.present, 0, message->param.notifyinfo.voip, message->param.notifyinfo.intern, NULL));
3501 message_put(message);
3502 logmessage(message);
3503 portlist = portlist->next;
3507 /* call sends messages to the endpoint
3509 void EndpointAppPBX::ea_message_call(unsigned long call_id, int message_type, union parameter *param)
3511 struct port_list *portlist;
3512 struct message *message;
3516 PERROR("EPOINT(%d) error: call == NULL.\n", ea_endpoint->ep_serial);
3520 portlist = ea_endpoint->ep_portlist;
3522 /* send MESSAGE_DATA to port */
3523 if (call_id == ea_endpoint->ep_call_id)
3525 if (message_type == MESSAGE_DATA)
3527 /* skip if no port relation */
3530 /* skip if more than one port relation */
3533 /* send audio data to port */
3534 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_DATA);
3535 memcpy(&message->param, param, sizeof(union parameter));
3536 message_put(message);
3541 // PDEBUG(DEBUG_EPOINT, "EPOINT(%d) received message %d for active call (terminal %s, caller id %s state=%d)\n", ea_endpoint->ep_serial, message, e_terminal, e_callerinfo.id, e_state);
3542 switch(message_type)
3544 /* CALL SENDS CRYPT message */
3546 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received crypt message: '%d'\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id, param->crypt.type);
3547 call_crypt(portlist, message_type, param);
3550 /* CALL sends INFORMATION message */
3551 case MESSAGE_INFORMATION:
3552 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received more digits: '%s'\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id, param->information.number);
3553 call_information(portlist, message_type, param);
3556 /* CALL sends FACILITY message */
3557 case MESSAGE_FACILITY:
3558 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received facility\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3559 call_facility(portlist, message_type, param);
3562 /* CALL sends OVERLAP message */
3563 case MESSAGE_OVERLAP:
3564 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received 'more info available'\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3565 if (e_state!=EPOINT_STATE_IN_SETUP
3566 && e_state!=EPOINT_STATE_IN_OVERLAP)
3568 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in setup state.\n", ea_endpoint->ep_serial);
3571 call_overlap(portlist, message_type, param);
3574 /* CALL sends PROCEEDING message */
3575 case MESSAGE_PROCEEDING:
3576 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s (caller id '%s') received proceeding\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3577 if(e_state!=EPOINT_STATE_IN_OVERLAP)
3579 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in setup state.\n", ea_endpoint->ep_serial);
3582 call_proceeding(portlist, message_type, param);
3585 /* CALL sends ALERTING message */
3586 case MESSAGE_ALERTING:
3587 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received alerting\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3588 if (e_state!=EPOINT_STATE_IN_OVERLAP
3589 && e_state!=EPOINT_STATE_IN_PROCEEDING)
3591 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in setup or proceeding state.\n", ea_endpoint->ep_serial);
3594 call_alerting(portlist, message_type, param);
3597 /* CALL sends CONNECT message */
3598 case MESSAGE_CONNECT:
3599 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received connect\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3600 if (e_state!=EPOINT_STATE_IN_OVERLAP
3601 && e_state!=EPOINT_STATE_IN_PROCEEDING
3602 && e_state!=EPOINT_STATE_IN_ALERTING)
3604 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in setup, proceeding or alerting state.\n", ea_endpoint->ep_serial);
3607 call_connect(portlist, message_type, param);
3610 /* CALL sends DISCONNECT/RELEASE message */
3611 case MESSAGE_DISCONNECT: /* call disconnect */
3612 case MESSAGE_RELEASE: /* call releases */
3613 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received %s with cause %d location %d\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id, (message_type==MESSAGE_DISCONNECT)?"disconnect":"release", param->disconnectinfo.cause, param->disconnectinfo.location);
3614 call_disconnect_release(portlist, message_type, param);
3617 /* CALL sends SETUP message */
3619 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint received setup from terminal='%s',id='%s' to id='%s' (dialing itype=%d)\n", ea_endpoint->ep_serial, param->setup.callerinfo.intern, param->setup.callerinfo.id, param->setup.dialinginfo.number, param->setup.dialinginfo.itype);
3620 call_setup(portlist, message_type, param);
3624 /* CALL sends special mISDNSIGNAL message */
3625 case MESSAGE_mISDNSIGNAL: /* isdn message to port */
3626 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received mISDNsignal message.\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3627 call_mISDNsignal(portlist, message_type, param);
3630 /* CALL has pattern available */
3631 case MESSAGE_PATTERN: /* indicating pattern available */
3632 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received pattern availability.\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3633 if (!e_call_pattern)
3635 PDEBUG(DEBUG_EPOINT, "-> pattern becomes available\n");
3640 set_tone(portlist, NULL);
3641 portlist = portlist->next;
3643 /* connect our audio tx and rx (blueboxing should be possibe before connect :)*/
3644 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
3645 message->param.channel = CHANNEL_STATE_CONNECT;
3646 message_put(message);
3647 // /* tell remote epoint to connect audio also, because we like to hear the patterns */
3648 // message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_REMOTE_AUDIO);
3649 // message->param.channel = CHANNEL_STATE_CONNECT;
3650 // message_put(message);
3651 // patterns are available, remote already connected audio
3655 /* CALL has no pattern available */
3656 case MESSAGE_NOPATTERN: /* indicating no pattern available */
3657 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received pattern NOT available.\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3660 PDEBUG(DEBUG_EPOINT, "-> pattern becomes unavailable\n");
3662 /* disconnect our audio tx and rx */
3663 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
3664 message->param.channel = CHANNEL_STATE_HOLD;
3665 message_put(message);
3670 /* CALL (dunno at the moment) */
3671 case MESSAGE_REMOTE_AUDIO:
3672 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received audio remote request.\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3673 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
3674 message->param.channel = param->channel;
3675 message_put(message);
3679 /* CALL sends a notify message */
3680 case MESSAGE_NOTIFY:
3681 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received notify.\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3682 call_notify(portlist, message_type, param);
3686 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);
3691 /* pick_call will connect the first incoming call found. the endpoint
3692 * will receivce a MESSAGE_CONNECT.
3694 int match_list(char *list, char *item)
3696 char *end, *next = NULL;
3698 /* no list make matching */
3704 /* eliminate white spaces */
3705 while (*list <= ' ')
3712 /* if end of list is reached, we return */
3713 if (list[0] == '\0')
3715 /* if we have more than one entry (left) */
3716 if ((end = strchr(list, ',')))
3719 next = end = strchr(list, '\0');
3720 while (*(end-1) <= ' ')
3722 /* if string part matches item */
3723 if (!strncmp(list, item, end-list))
3729 void EndpointAppPBX::pick_call(char *extensions)
3731 struct message *message;
3732 struct port_list *portlist;
3734 class EndpointAppPBX *eapp, *found;
3736 class CallPBX *callpbx;
3737 struct call_relation *relation;
3740 /* find an endpoint that is ringing internally or vbox with higher priority */
3743 eapp = apppbx_first;
3746 if (eapp!=this && ea_endpoint->ep_portlist)
3748 portlist = eapp->ea_endpoint->ep_portlist;
3751 if ((port = find_port_id(portlist->port_id)))
3753 if (port->p_type == PORT_TYPE_VBOX_OUT)
3755 if (match_list(extensions, eapp->e_terminal))
3762 if ((port->p_type==PORT_TYPE_DSS1_NT_OUT || port->p_type==PORT_TYPE_DSS1_TE_OUT)
3763 && port->p_state==PORT_STATE_OUT_ALERTING)
3764 if (match_list(extensions, eapp->e_terminal))
3769 portlist = portlist->next;
3777 /* if no endpoint found */
3780 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) nobody is ringing internally (or we don't have her in the access list), so we disconnect.\n", ea_endpoint->ep_serial);
3782 set_tone(ea_endpoint->ep_portlist, "cause_10");
3783 message_disconnect_port(ea_endpoint->ep_portlist, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, "");
3784 new_state(EPOINT_STATE_OUT_DISCONNECT);
3789 if (ea_endpoint->ep_call_id)
3791 PERROR("EPOINT(%d) we already have a call. SOFTWARE ERROR.\n", ea_endpoint->ep_serial);
3794 if (!eapp->ea_endpoint->ep_call_id)
3796 PERROR("EPOINT(%d) ringing endpoint has no call.\n", ea_endpoint->ep_serial);
3799 call = find_call_id(eapp->ea_endpoint->ep_call_id);
3802 PERROR("EPOINT(%d) ringing endpoint's call not found.\n", ea_endpoint->ep_serial);
3805 if (callpbx->c_type != CALL_TYPE_PBX)
3807 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ringing endpoint's call is not a PBX call, so we must reject.\n", ea_endpoint->ep_serial);
3810 callpbx = (class CallPBX *)call;
3811 relation = callpbx->c_relation;
3814 PERROR("EPOINT(%d) ringing endpoint's call has no relation. SOFTWARE ERROR.\n", ea_endpoint->ep_serial);
3817 while (relation->epoint_id != eapp->ea_endpoint->ep_serial)
3819 relation = relation->next;
3822 PERROR("EPOINT(%d) ringing endpoint's call has no relation to that call. SOFTWARE ERROR.\n", ea_endpoint->ep_serial);
3827 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) found ringing endpoint: %d.\n", ea_endpoint->ep_serial, eapp->ea_endpoint->ep_serial);
3829 if (options.deb & DEBUG_EPOINT)
3831 class Call *debug_c = call_first;
3832 class Endpoint *debug_e = epoint_first;
3833 class Port *debug_p = port_first;
3835 callpbx_debug(callpbx, "EndpointAppPBX::pick_call(before)");
3837 PDEBUG(DEBUG_EPOINT, "showing all calls:\n");
3840 PDEBUG(DEBUG_EPOINT, "call=%ld\n", debug_c->c_serial);
3841 debug_c = debug_c->next;
3843 PDEBUG(DEBUG_EPOINT, "showing all endpoints:\n");
3846 PDEBUG(DEBUG_EPOINT, "ep=%ld, call=%ld\n", debug_e->ep_serial, debug_e->ep_call_id);
3847 debug_e = debug_e->next;
3849 PDEBUG(DEBUG_EPOINT, "showing all ports:\n");
3852 PDEBUG(DEBUG_EPOINT, "port=%ld, ep=%ld (active)\n", debug_p->p_serial, ACTIVE_EPOINT(debug_p->p_epointlist));
3853 debug_p = debug_p->next;
3858 ea_endpoint->ep_call_id = eapp->ea_endpoint->ep_call_id; /* we get the call */
3859 relation->epoint_id = ea_endpoint->ep_serial; /* the call gets us */
3860 eapp->ea_endpoint->ep_call_id = 0; /* the ringing endpoint will get disconnected */
3862 /* connnecting our endpoint */
3863 new_state(EPOINT_STATE_CONNECT);
3865 set_tone(ea_endpoint->ep_portlist, NULL);
3867 /* now we send a release to the ringing endpoint */
3868 message = message_create(ea_endpoint->ep_call_id, eapp->ea_endpoint->ep_serial, CALL_TO_EPOINT, MESSAGE_RELEASE);
3869 message->param.disconnectinfo.cause = 26; /* non selected user clearing */
3870 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
3871 message_put(message);
3873 /* we send a connect to the call with our caller id */
3874 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CONNECT);
3875 SCPY(message->param.connectinfo.id, e_callerinfo.id);
3876 message->param.connectinfo.present = e_callerinfo.present;
3877 message->param.connectinfo.screen = e_callerinfo.screen;
3878 message->param.connectinfo.itype = e_callerinfo.itype;
3879 message->param.connectinfo.ntype = e_callerinfo.ntype;
3880 message_put(message);
3882 /* we send a connect to our port with the remote callerid */
3883 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
3884 SCPY(message->param.connectinfo.id, eapp->e_callerinfo.id);
3885 message->param.connectinfo.present = eapp->e_callerinfo.present;
3886 message->param.connectinfo.screen = eapp->e_callerinfo.screen;
3887 message->param.connectinfo.itype = eapp->e_callerinfo.itype;
3888 message->param.connectinfo.ntype = eapp->e_callerinfo.ntype;
3889 /* handle restricted caller ids */
3890 apply_callerid_restriction(e_ext.anon_ignore, ea_endpoint->ep_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);
3891 /* display callerid if desired for extension */
3892 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));
3893 message_put(message);
3895 /* we send a connect to the audio path (not for vbox) */
3896 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
3897 message->param.channel = CHANNEL_STATE_CONNECT;
3898 message_put(message);
3900 /* beeing paranoid, we make call update */
3901 callpbx->c_mixer = 1;
3903 if (options.deb & DEBUG_EPOINT)
3905 class Call *debug_c = call_first;
3906 class Endpoint *debug_e = epoint_first;
3907 class Port *debug_p = port_first;
3909 callpbx_debug(callpbx, "EndpointAppPBX::pick_call(after)");
3911 PDEBUG(DEBUG_EPOINT, "showing all calls:\n");
3914 PDEBUG(DEBUG_EPOINT, "call=%ld\n", debug_c->c_serial);
3915 debug_c = debug_c->next;
3917 PDEBUG(DEBUG_EPOINT, "showing all endpoints:\n");
3920 PDEBUG(DEBUG_EPOINT, "ep=%ld, call=%ld\n", debug_e->ep_serial, debug_e->ep_call_id);
3921 debug_e = debug_e->next;
3923 PDEBUG(DEBUG_EPOINT, "showing all ports:\n");
3926 PDEBUG(DEBUG_EPOINT, "port=%ld, ep=%ld\n", debug_p->p_serial, ACTIVE_EPOINT(debug_p->p_epointlist));
3927 debug_p = debug_p->next;
3933 /* join calls (look for a call that is on hold (same isdn interface/terminal))
3935 void EndpointAppPBX::join_call(void)
3937 struct message *message;
3938 struct call_relation *our_relation, *other_relation;
3939 struct call_relation **our_relation_pointer, **other_relation_pointer;
3940 class Call *our_call, *other_call;
3941 class CallPBX *our_callpbx, *other_callpbx;
3942 class EndpointAppPBX *other_eapp; class Endpoint *temp_epoint;
3943 class Port *our_port, *other_port;
3944 class Pdss1 *our_pdss1, *other_pdss1;
3946 /* are we a candidate to join a call */
3947 our_call = find_call_id(ea_endpoint->ep_call_id);
3950 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: our call doesn't exist anymore.\n", ea_endpoint->ep_serial);
3953 if (our_call->c_type != CALL_TYPE_PBX)
3955 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: call is not a pbx call.\n", ea_endpoint->ep_serial);
3958 our_callpbx = (class CallPBX *)our_call;
3959 if (!ea_endpoint->ep_portlist)
3961 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: we have no port.\n", ea_endpoint->ep_serial);
3966 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: we are not internal extension.\n", ea_endpoint->ep_serial);
3969 our_port = find_port_id(ea_endpoint->ep_portlist->port_id);
3972 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: our port doesn't exist anymore.\n", ea_endpoint->ep_serial);
3975 if ((our_port->p_type&PORT_CLASS_mISDN_MASK) != PORT_CLASS_mISDN_DSS1)
3977 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: our port is not isdn.\n", ea_endpoint->ep_serial);
3980 our_pdss1 = (class Pdss1 *)our_port;
3982 /* find an endpoint that is on hold and has the same mISDNport that we are on */
3983 other_eapp = apppbx_first;
3986 if (other_eapp == this)
3988 other_eapp = other_eapp->next;
3991 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) comparing other endpoint candiate: (ep%d) terminal='%s' port=%s call=%d.\n", ea_endpoint->ep_serial, other_eapp->ea_endpoint->ep_serial, other_eapp->e_terminal, (other_eapp->ea_endpoint->ep_portlist)?"YES":"NO", other_eapp->ea_endpoint->ep_call_id);
3992 if (other_eapp->e_terminal[0] /* has terminal */
3993 && other_eapp->ea_endpoint->ep_portlist /* has port */
3994 && other_eapp->ea_endpoint->ep_call_id) /* has call */
3996 other_port = find_port_id(other_eapp->ea_endpoint->ep_portlist->port_id);
3997 if (other_port) /* port still exists */
3999 if (other_port->p_type==PORT_TYPE_DSS1_NT_OUT
4000 || other_port->p_type==PORT_TYPE_DSS1_NT_IN) /* port is isdn nt-mode */
4002 other_pdss1 = (class Pdss1 *)other_port;
4003 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) comparing other endpoint's port is of type isdn! comparing our portnum=%d with other's portnum=%d hold=%s ces=%d\n", ea_endpoint->ep_serial, our_pdss1->p_m_mISDNport->portnum, other_pdss1->p_m_mISDNport->portnum, (other_pdss1->p_m_hold)?"YES":"NO", other_pdss1->p_m_d_ces);
4004 if (other_pdss1->p_m_hold /* port is on hold */
4005 && other_pdss1->p_m_mISDNport == our_pdss1->p_m_mISDNport /* same isdn interface */
4006 && other_pdss1->p_m_d_ces == our_pdss1->p_m_d_ces) /* same tei+sapi */
4010 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) comparing other endpoint's port is of other type!\n", ea_endpoint->ep_serial);
4014 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) comparing other endpoint's port doesn't exist enymore.\n", ea_endpoint->ep_serial);
4017 other_eapp = other_eapp->next;
4021 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: no other endpoint on same isdn interface with port on hold.\n", ea_endpoint->ep_serial);
4024 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) port on hold found.\n", ea_endpoint->ep_serial);
4026 /* if we have the same call */
4027 if (other_eapp->ea_endpoint->ep_call_id == ea_endpoint->ep_call_id)
4029 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: we an the other have the same call.\n", ea_endpoint->ep_serial);
4032 other_call = find_call_id(other_eapp->ea_endpoint->ep_call_id);
4035 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: other call doesn't exist anymore.\n", ea_endpoint->ep_serial);
4038 if (other_call->c_type != CALL_TYPE_PBX)
4040 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: other call is not a pbx call.\n", ea_endpoint->ep_serial);
4043 other_callpbx = (class CallPBX *)other_call;
4044 if (our_callpbx->c_partyline && other_callpbx->c_partyline)
4046 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: both calls are partylines.\n", ea_endpoint->ep_serial);
4050 /* remove relation to endpoint for call on hold */
4051 other_relation = other_callpbx->c_relation;
4052 other_relation_pointer = &other_callpbx->c_relation;
4053 while(other_relation)
4055 if (other_relation->epoint_id == other_eapp->ea_endpoint->ep_serial)
4057 /* detach other endpoint on hold */
4058 *other_relation_pointer = other_relation->next;
4059 memset(other_relation, 0, sizeof(struct call_relation));
4060 free(other_relation);
4062 other_relation = *other_relation_pointer;
4063 other_eapp->ea_endpoint->ep_call_id = NULL;
4067 /* change call/hold pointer of endpoint to the new call */
4068 temp_epoint = find_epoint_id(other_relation->epoint_id);
4071 if (temp_epoint->ep_call_id == other_call->c_serial)
4072 temp_epoint->ep_call_id = our_call->c_serial;
4075 other_relation_pointer = &other_relation->next;
4076 other_relation = other_relation->next;
4078 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) endpoint on hold removed, other enpoints on call relinked (to our call).\n", ea_endpoint->ep_serial);
4080 /* join call relations */
4081 our_relation = our_callpbx->c_relation;
4082 our_relation_pointer = &our_callpbx->c_relation;
4085 our_relation_pointer = &our_relation->next;
4086 our_relation = our_relation->next;
4088 *our_relation_pointer = other_callpbx->c_relation;
4089 other_callpbx->c_relation = NULL;
4090 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) relations joined.\n", ea_endpoint->ep_serial);
4092 /* release endpoint on hold */
4093 message = message_create(other_callpbx->c_serial, other_eapp->ea_endpoint->ep_serial, CALL_TO_EPOINT, MESSAGE_RELEASE);
4094 message->param.disconnectinfo.cause = CAUSE_NORMAL; /* normal */
4095 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
4096 message_put(message);
4098 /* if we are not a partyline, we get partyline state from other call */
4099 our_callpbx->c_partyline += other_callpbx->c_partyline;
4101 /* remove empty call */
4103 PDEBUG(DEBUG_EPOINT, "EPOINT(%d)d-call completely removed!\n");
4105 /* mixer must update */
4106 our_callpbx->c_mixer = 1; /* update mixer flag */
4108 /* we send a retrieve to that endpoint */
4109 // mixer will update the hold-state of the call and send it to the endpoints is changes
4113 /* check if we have an external call
4114 * this is used to check for encryption ability
4116 int EndpointAppPBX::check_external(char **errstr, class Port **port)
4118 struct call_relation *relation;
4120 class CallPBX *callpbx;
4121 class Endpoint *epoint;
4123 /* some paranoia check */
4124 if (!ea_endpoint->ep_portlist)
4126 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) error: we have no port.\n", ea_endpoint->ep_serial);
4127 *errstr = "No Call";
4132 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) error: we are not internal extension.\n", ea_endpoint->ep_serial);
4133 *errstr = "No Call";
4137 /* check if we have a call with 2 parties */
4138 call = find_call_id(ea_endpoint->ep_call_id);
4141 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) we have currently no call.\n", ea_endpoint->ep_serial);
4142 *errstr = "No Call";
4145 if (call->c_type != CALL_TYPE_PBX)
4147 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call is nto a pbx call.\n", ea_endpoint->ep_serial);
4148 *errstr = "No PBX Call";
4151 callpbx = (class CallPBX *)call;
4152 relation = callpbx->c_relation;
4155 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call has no relation.\n", ea_endpoint->ep_serial);
4156 *errstr = "No Call";
4159 if (!relation->next)
4161 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call has no 2nd relation.\n", ea_endpoint->ep_serial);
4162 *errstr = "No Call";
4165 if (relation->next->next)
4167 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call has more than two relations.\n", ea_endpoint->ep_serial);
4168 *errstr = "Err: Conference";
4171 if (relation->epoint_id == ea_endpoint->ep_serial)
4173 relation = relation->next;
4174 if (relation->epoint_id == ea_endpoint->ep_serial)
4176 PERROR("EPOINT(%d) SOFTWARE ERROR: both call relations are related to our endpoint.\n", ea_endpoint->ep_serial);
4177 *errstr = "Software Error";
4182 /* check remote port for external call */
4183 epoint = find_epoint_id(relation->epoint_id);
4186 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call has no 2nd endpoint.\n", ea_endpoint->ep_serial);
4187 *errstr = "No Call";
4190 if (!epoint->ep_portlist)
4192 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) 2nd endpoint has not port.\n", ea_endpoint->ep_serial);
4193 *errstr = "No Call";
4196 *port = find_port_id(epoint->ep_portlist->port_id);
4199 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) 2nd endpoint has an none existing port.\n", ea_endpoint->ep_serial);
4200 *errstr = "No Call";
4203 if (((*port)->p_type&PORT_CLASS_mISDN_MASK)!=PORT_CLASS_mISDN_DSS1) /* port is not external isdn */
4205 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) 2nd endpoint has not an external port.\n", ea_endpoint->ep_serial);
4206 *errstr = "No Ext Call";
4209 if ((*port)->p_state != PORT_STATE_CONNECT)
4211 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) 2nd endpoint's port is not in connected state.\n", ea_endpoint->ep_serial);
4212 *errstr = "No Ext Connect";
4218 void EndpointAppPBX::logmessage(struct message *message)
4222 char *logtext = "unknown";
4225 if (message->flow != EPOINT_TO_PORT)
4227 PERROR("EPOINT(%d) message not of correct flow type-\n", ea_endpoint->ep_serial);
4231 switch(message->type)
4234 port = find_port_id(message->id_to);
4237 if (port->p_type == PORT_TYPE_DSS1_NT_OUT)
4239 pdss1 = (class Pdss1 *)port;
4240 printlog("%3d outgoing SETUP from %s='%s'%s%s%s%s to intern='%s' port='%d' (NT)\n",
4241 ea_endpoint->ep_serial,
4242 (message->param.setup.callerinfo.intern[0])?"intern":"extern",
4243 (message->param.setup.callerinfo.intern[0])?e_callerinfo.intern:e_callerinfo.id,
4244 (message->param.setup.callerinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
4245 (message->param.setup.redirinfo.id[0])?"redirected='":"",
4246 message->param.setup.redirinfo.id,
4247 (message->param.setup.redirinfo.id[0])?"'":"",
4248 message->param.setup.dialinginfo.number,
4249 pdss1->p_m_mISDNport->portnum
4252 if (port->p_type == PORT_TYPE_DSS1_TE_OUT)
4254 pdss1 = (class Pdss1 *)port;
4255 printlog("%3d outgoing SETUP from %s='%s'%s%s%s%s to extern='%s' port='%d' (TE)\n",
4256 ea_endpoint->ep_serial,
4257 (message->param.setup.callerinfo.intern[0])?"intern":"extern",
4258 (message->param.setup.callerinfo.intern[0])?e_callerinfo.intern:e_callerinfo.id,
4259 (message->param.setup.callerinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
4260 (message->param.setup.redirinfo.id[0])?"redirected='":"",
4261 message->param.setup.redirinfo.id,
4262 (message->param.setup.redirinfo.id[0])?"'":"",
4263 message->param.setup.dialinginfo.number,
4264 pdss1->p_m_mISDNport->portnum
4267 if (port->p_type == PORT_TYPE_H323_OUT)
4269 printlog("%3d outgoing SETUP from %s='%s'%s%s%s%s to h323='%s'\n",
4270 ea_endpoint->ep_serial,
4271 (message->param.setup.callerinfo.intern[0])?"intern":"extern",
4272 (message->param.setup.callerinfo.intern[0])?e_callerinfo.intern:e_callerinfo.id,
4273 (message->param.setup.callerinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
4274 (message->param.setup.redirinfo.id[0])?"redirected='":"",
4275 message->param.setup.redirinfo.id,
4276 (message->param.setup.redirinfo.id[0])?"'":"",
4277 message->param.setup.dialinginfo.number
4280 if (port->p_type == PORT_TYPE_SIP_OUT)
4282 printlog("%3d outgoing SETUP from %s='%s'%s%s%s%s to sip='%s'\n",
4283 ea_endpoint->ep_serial,
4284 (message->param.setup.callerinfo.intern[0])?"intern":"extern",
4285 (message->param.setup.callerinfo.intern[0])?e_callerinfo.intern:e_callerinfo.id,
4286 (message->param.setup.callerinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
4287 (message->param.setup.redirinfo.id[0])?"redirected='":"",
4288 message->param.setup.redirinfo.id,
4289 (message->param.setup.redirinfo.id[0])?"'":"",
4290 message->param.setup.dialinginfo.number
4293 if (port->p_type == PORT_TYPE_VBOX_OUT)
4295 printlog("%3d outgoing SETUP from %s='%s'%s%s%s%s to vbox='%s'\n",
4296 ea_endpoint->ep_serial,
4297 (message->param.setup.callerinfo.intern[0])?"intern":"extern",
4298 (message->param.setup.callerinfo.intern[0])?e_callerinfo.intern:e_callerinfo.id,
4299 (message->param.setup.callerinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
4300 (message->param.setup.redirinfo.id[0])?"redirected='":"",
4301 message->param.setup.redirinfo.id,
4302 (message->param.setup.redirinfo.id[0])?"'":"",
4303 message->param.setup.dialinginfo.number
4308 case MESSAGE_OVERLAP:
4309 printlog("%3d outgoing SETUP ACKNOWLEDGE\n",
4310 ea_endpoint->ep_serial
4314 case MESSAGE_PROCEEDING:
4315 printlog("%3d outgoing PROCEEDING\n",
4316 ea_endpoint->ep_serial
4320 case MESSAGE_ALERTING:
4321 printlog("%3d outgoing ALERTING\n",
4322 ea_endpoint->ep_serial
4326 case MESSAGE_CONNECT:
4327 printlog("%3d outgoing CONNECT id='%s'%s\n",
4328 ea_endpoint->ep_serial,
4329 message->param.connectinfo.id,
4330 (message->param.connectinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":""
4334 case MESSAGE_DISCONNECT:
4335 printlog("%3d outgoing DISCONNECT cause='%d' (%s) location='%d' (%s) display='%s'\n",
4336 ea_endpoint->ep_serial,
4337 message->param.disconnectinfo.cause,
4338 (message->param.disconnectinfo.cause>0 && message->param.disconnectinfo.cause<128)?isdn_cause[message->param.disconnectinfo.cause].english:"-",
4339 message->param.disconnectinfo.location,
4340 (message->param.disconnectinfo.location>=0 && message->param.disconnectinfo.location<16)?isdn_location[message->param.disconnectinfo.location].english:"-",
4341 message->param.disconnectinfo.display
4345 case MESSAGE_RELEASE:
4346 printlog("%3d outgoing RELEASE cause='%d' (%s) location='%d' (%s)\n",
4347 ea_endpoint->ep_serial,
4348 message->param.disconnectinfo.cause,
4349 (message->param.disconnectinfo.cause>0 && message->param.disconnectinfo.cause<128)?isdn_cause[message->param.disconnectinfo.cause].english:"-",
4350 message->param.disconnectinfo.location,
4351 (message->param.disconnectinfo.location>=0 && message->param.disconnectinfo.location<16)?isdn_location[message->param.disconnectinfo.location].english:"-"
4355 case MESSAGE_NOTIFY:
4356 switch(message->param.notifyinfo.notify)
4362 logtext = "USER_SUSPENDED";
4365 logtext = "BEARER_SERVICE_CHANGED";
4368 logtext = "USER_RESUMED";
4371 logtext = "CONFERENCE_ESTABLISHED";
4374 logtext = "CONFERENCE_DISCONNECTED";
4377 logtext = "OTHER_PARTY_ADDED";
4380 logtext = "ISOLATED";
4383 logtext = "REATTACHED";
4386 logtext = "OTHER_PARTY_ISOLATED";
4389 logtext = "OTHER_PARTY_REATTACHED";
4392 logtext = "OTHER_PARTY_SPLIT";
4395 logtext = "OTHER_PARTY_DISCONNECTED";
4398 logtext = "CONFERENCE_FLOATING";
4401 logtext = "CONFERENCE_DISCONNECTED_PREEMTED";
4404 logtext = "CONFERENCE_FLOATING_SERVED_USER_PREEMTED";
4407 logtext = "CALL_IS_A_WAITING_CALL";
4410 logtext = "DIVERSION_ACTIVATED";
4413 logtext = "RESERVED_CT_1";
4416 logtext = "RESERVED_CT_2";
4419 logtext = "REVERSE_CHARGING";
4422 logtext = "REMOTE_HOLD";
4425 logtext = "REMOTE_RETRIEVAL";
4428 logtext = "CALL_IS_DIVERTING";
4431 SPRINT(buffer, "indicator=%d", message->param.notifyinfo.notify - 0x80);
4435 printlog("%3d outgoing NOTIFY notify='%s' id='%s'%s display='%s'\n",
4436 ea_endpoint->ep_serial,
4438 message->param.notifyinfo.id,
4439 (message->param.notifyinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
4440 message->param.notifyinfo.display
4444 case MESSAGE_INFORMATION:
4445 printlog("%3d outgoing INFORMATION information='%s'\n",
4446 ea_endpoint->ep_serial,
4447 message->param.information.number
4451 case MESSAGE_FACILITY:
4452 printlog("%3d outgoing FACILITY len='%d'\n",
4453 ea_endpoint->ep_serial,
4454 message->param.facilityinfo.len
4459 printlog("%3d outgoing TONE dir='%s' name='%s'\n",
4460 ea_endpoint->ep_serial,
4461 message->param.tone.dir,
4462 message->param.tone.name
4467 PERROR("EPOINT(%d) message not of correct type (%d)\n", ea_endpoint->ep_serial, message->type);
4471 void EndpointAppPBX::message_disconnect_port(struct port_list *portlist, int cause, int location, char *display)
4473 struct message *message;
4477 if (!portlist->port_id)
4480 if (!e_connectedmode)
4482 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_DISCONNECT);
4483 message->param.disconnectinfo.cause = cause;
4484 message->param.disconnectinfo.location = location;
4486 SCPY(message->param.disconnectinfo.display, display);
4488 SCPY(message->param.disconnectinfo.display, get_isdn_cause(cause, location, e_ext.display_cause));
4491 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
4493 SCPY(message->param.notifyinfo.display, display);
4495 SCPY(message->param.notifyinfo.display, get_isdn_cause(cause, location, e_ext.display_cause));
4497 message_put(message);
4498 logmessage(message);