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 /* external ports receive no restricted caller id */
283 if (port_type==PORT_TYPE_DSS1_TE_IN || port_type==PORT_TYPE_DSS1_TE_OUT)
286 /* if we enabled anonymouse ignore */
290 /* else we remove the caller id */
294 *ntype = INFO_NTYPE_UNKNOWN;
296 // *screen = INFO_SCREEN_USER;
297 // maybe we should not make voip address anonymous
300 // maybe it's no fraud to present internal id
307 /* used display message to display callerid as available */
308 char *EndpointAppPBX::apply_callerid_display(char *id, int itype, int ntype, int present, int screen, char *voip, char *intern, char *name)
310 static char display[81];
313 char *cid = numberrize_callerinfo(id, ntype);
315 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");
326 /* NOTE: is caller is is not available for this extesion, it has been removed by apply_callerid_restriction already */
328 /* internal extension's caller id */
329 if (intern[0] && e_ext.display_int)
332 SCAT(display, intern);
335 if (itype == INFO_ITYPE_VBOX)
336 SCAT(display, "(vbox)");
338 SCAT(display, "(int)");
341 /* external caller id */
342 if (!intern[0] && !voip[0] && e_ext.display_ext)
348 if (present == INFO_PRESENT_RESTRICTED)
349 SCAT(display, "anonymous");
351 SCAT(display, "unknown");
359 if (voip[0] && e_ext.display_voip)
361 if (!display[0] && cid[0])
368 /* display if callerid is anonymouse but available due anon-ignore */
369 if (e_ext.display_anon && present==INFO_PRESENT_RESTRICTED)
372 SCAT(display, "unknown");
375 SCAT(display, " anon");
378 /* display if callerid is anonymouse but available due anon-ignore */
379 if (e_ext.display_fake && screen==INFO_SCREEN_USER && present!=INFO_PRESENT_NULL)
385 if (present == INFO_PRESENT_RESTRICTED)
386 SCAT(display, "anonymous");
388 SCAT(display, "unknown");
393 SCAT(display, " fake");
397 if (name[0] && e_ext.display_name)
399 if (!display[0] && cid[0])
410 * uses the current state to notify activity
412 void EndpointAppPBX::notify_active(void)
414 struct port_list *portlist = ea_endpoint->ep_portlist;
415 struct message *message;
420 case NOTIFY_STATE_ACTIVE:
421 /* we are already active, so we don't do anything */
424 case NOTIFY_STATE_SUSPEND:
425 notify = INFO_NOTIFY_USER_RESUMED;
428 set_tone(portlist, NULL);
429 portlist = portlist->next;
431 portlist = ea_endpoint->ep_portlist;
434 case NOTIFY_STATE_HOLD:
435 notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
438 set_tone(portlist, NULL);
439 portlist = portlist->next;
441 portlist = ea_endpoint->ep_portlist;
444 case NOTIFY_STATE_CONFERENCE:
445 notify = INFO_NOTIFY_CONFERENCE_DISCONNECTED;
448 set_tone(portlist, NULL);
449 portlist = portlist->next;
451 portlist = ea_endpoint->ep_portlist;
455 PERROR("unknown e_tx_state = %d\n", e_tx_state);
461 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
462 message->param.notifyinfo.notify = notify;
463 message_put(message);
465 portlist = portlist->next;
471 * keypad functions during call. one example to use this is to put a call on hold or start a conference
473 void EndpointAppPBX::keypad_function(char digit)
476 /* we must be in a call, in order to send messages to the call */
477 if (e_terminal[0] == '\0')
479 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) IGNORING keypad received not from extension.\n", ea_endpoint->ep_serial);
485 /* join conference */
487 if (ea_endpoint->ep_call_id == 0)
489 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) keypad received during connect but not during a call.\n", ea_endpoint->ep_serial);
492 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) join call with call on hold\n", ea_endpoint->ep_serial);
498 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) shared key encryption selected.\n", ea_endpoint->ep_serial);
502 /* crypt key-exchange */
504 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) key exchange encryption selected.\n", ea_endpoint->ep_serial);
510 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption off selected.\n", ea_endpoint->ep_serial);
515 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) unsupported keypad digit '%c'.\n", ea_endpoint->ep_serial, digit);
520 /* set tone pattern for port */
521 void EndpointAppPBX::set_tone(struct port_list *portlist, char *tone)
523 struct message *message;
528 /* store for suspended processes */
533 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) no endpoint to notify tone.\n", ea_endpoint->ep_serial);
537 if (e_call_pattern /* pattern are provided */
538 && !(e_ext.own_setup && e_state == EPOINT_STATE_IN_SETUP)
539 && !(e_ext.own_setup && e_state == EPOINT_STATE_IN_OVERLAP)
540 && !(e_ext.own_proceeding && e_state == EPOINT_STATE_IN_PROCEEDING)
541 && !(e_ext.own_alerting && e_state == EPOINT_STATE_IN_ALERTING)
542 && !(e_ext.own_cause && e_state == EPOINT_STATE_IN_DISCONNECT)
543 && !(e_ext.own_setup && e_state == EPOINT_STATE_OUT_SETUP)
544 && !(e_ext.own_setup && e_state == EPOINT_STATE_OUT_OVERLAP)
545 && !(e_ext.own_proceeding && e_state == EPOINT_STATE_OUT_PROCEEDING)
546 && !(e_ext.own_alerting && e_state == EPOINT_STATE_OUT_ALERTING)
547 && !(e_ext.own_cause && e_state == EPOINT_STATE_OUT_DISCONNECT)
548 && tone[0] && !!strncmp(tone,"crypt_*",6))
550 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) tone not provided since patterns are available\n", ea_endpoint->ep_serial);
556 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_TONE);
557 SCPY(message->param.tone.dir, e_ext.tones_dir[0]?e_ext.tones_dir:options.tones_dir);
558 SCPY(message->param.tone.name, tone);
559 message_put(message);
566 * hunts an mISDNport that is available for an outgoing call
567 * if no ifname was given, any interface that is not an extension
570 static struct mISDNport *EndpointAppPBX::hunt_port(char *ifname, int *channel)
572 struct interface *interface;
573 struct mISDNport *mISDNport;
575 interface = interface_first;
577 /* first find the given interface or, if not given, one with no extension */
582 /* check for given interface */
585 if (!strcasecmp(interface->name, ifname))
587 /* found explicit interface */
588 printlog("%3d interface %s found as given\n", ea_endpoint->ep_serial, ifname);
594 if (!interface->extension)
596 /* found non extension */
597 printlog("%3d interface %s found, that is not an extension\n", ea_endpoint->ep_serial, interface->name);
602 interface = interface->next;
605 /* see if interface has ports */
606 if (!interface->ifport)
609 printlog("%3d interface %s has no active ports, skipping.\n", ea_endpoint->ep_serial, interface->name);
610 interface = interface->next;
614 /* select port by algorithm */
615 ifport_start = interface->port;
617 if (interface->hunt == HUNT_ROUNDROBIN)
619 while(ifport_start->next && index<interface->hunt_next)
621 ifport_start = ifport_start->next;
624 printlog("%3d starting with port#%d position %d (round-robin)\n", ea_endpoint->ep_serial, ifport_start->portnum, index);
628 ifport = ifport_start;
631 /* see if port is available */
632 if (!ifport->mISDNport)
634 printlog("%3d port#%d position %d is not available, skipping.\n", ea_endpoint->ep_serial, ifport_start->portnum, index);
637 mISDNport = ifport->mISDNport;
639 #warning admin block auch bei incomming calls
640 #warning calls releasen, wenn port entfernt wird, geblockt wird
641 /* see if port is administratively blocked */
644 printlog("%3d port#%d position %d is administratively blocked, skipping.\n", ea_endpoint->ep_serial, ifport_start->portnum, index);
648 /* see if link is up */
649 if (mISDNport->ptp && !mISDNport->l2link)
651 printlog("%3d port#%d position %d is ptp but layer 2 is down.\n", ea_endpoint->ep_serial, ifport_start->portnum, index);
652 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) skipping because it is PTP with L2 down\n", ea_endpoint->ep_serial);
656 /* check for channel form selection list */
658 selchannel = ifport->selchannel;
661 switch(selchannel->channel)
663 case CHANNEL_FREE: /* free channel */
664 if (mISDNport->b_inuse >= mISDNport->b_num)
665 break; /* all channel in use or reserverd */
668 while(i < mISDNport->b_num)
670 if (mISDNport->b_port[i] == NULL)
672 *channel = i+1+(i>=15);
673 printlog("%3d port#%d position %d selecting free channel %d\n", ea_endpoint->ep_serial, ifport_start->portnum, index, *channel);
680 case CHANNEL_ANY: /* don't ask for channel */
681 if (mISDNport->b_inuse >= mISDNport->b_num)
683 break; /* all channel in use or reserverd */
685 printlog("%3d port#%d position %d using with 'any channel'\n", ea_endpoint->ep_serial, ifport_start->portnum, index);
686 *channel = SEL_CHANNEL_ANY;
689 case CHANNEL_NO: /* call waiting */
690 printlog("%3d port#%d position %d using with 'no channel'\n", ea_endpoint->ep_serial, ifport_start->portnum, index);
691 *channel = SEL_CHANNEL_NO;
695 if (selchannel->channel<1 || selchannel->channel==16)
696 break; /* invalid channels */
697 i = selchannel->channel-1-(selchannel->channel>=17);
698 if (i >= mISDNport->b_num)
699 break; /* channel not in port */
700 if (mISDNport->b_port[i] == NULL)
702 *channel = selchannel->channel;
703 printlog("%3d port#%d position %d selecting given channel %d\n", ea_endpoint->ep_serial, ifport_start->portnum, index, *channel);
709 break; /* found channel */
710 printlog("%3d port#%d position %d skipping, because no channel found.\n", ea_endpoint->ep_serial, ifport_start->portnum, index);
711 selchannel = selchannel->next;
714 /* if channel was found, return mISDNport and channel */
717 /* setting next port to start next time */
718 if (interface->hunt == HUNT_ROUNDROBIN)
723 interface->hunt_next = index;
730 /* go next port, until all ports are checked */
732 ifport = ifport->next;
736 ifport = interface->ifport;
738 if (ifport != ifport_start)
741 return(NULL); /* no port found */
744 /* outgoing setup to port(s)
745 * ports will be created and a setup is sent if everything is ok. otherwhise
746 * the endpoint is destroyed.
748 void EndpointAppPBX::out_setup(void)
750 struct dialing_info dialinginfo;
752 // class pdss1 *pdss1;
753 struct port_list *portlist;
754 struct message *message;
756 int cause = CAUSE_RESSOURCEUNAVAIL;
759 struct mISDNport *mISDNport;
762 class EndpointAppPBX *atemp;
763 // char allowed_ports[256];
767 char ifname[sizeof(e_ext.interfaces)],
769 struct port_settings port_settings;
772 /* create settings for creating port */
773 memset(&port_settings, 0, sizeof(port_settings));
775 SCPY(port_settings.tones_dir, e_ext.tones_dir);
777 SCPY(port_settings.tones_dir, options.tones_dir);
778 port_settings.tout_setup = e_ext.tout_setup;
779 port_settings.tout_dialing = e_ext.tout_dialing;
780 port_settings.tout_proceeding = e_ext.tout_proceeding;
781 port_settings.tout_alerting = e_ext.tout_alerting;
782 port_settings.tout_disconnect = e_ext.tout_disconnect;
783 // port_settings.tout_hold = e_ext.tout_hold;
784 // port_settings.tout_park = e_ext.tout_park;
785 port_settings.no_seconds = e_ext.no_seconds;
787 /* 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 */
789 /* check what dialinginfo.itype we got */
790 switch(e_dialinginfo.itype)
792 /* *********************** call to extension or vbox */
793 case INFO_ITYPE_ISDN_EXTENSION:
794 /* check if we deny incoming calls when we use an extension */
795 if (e_ext.noknocking)
797 atemp = apppbx_first;
801 if (!strcmp(atemp->e_terminal, e_terminal))
807 PERROR("EPOINT(%d) noknocking and currently a call\n", ea_endpoint->ep_serial);
808 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_BUSY, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYSPE_ call, port */
809 return; /* must exit here */
812 /* FALL THROUGH !!!! */
813 case INFO_ITYPE_VBOX:
814 /* get dialed extension's info */
815 // SCPY(exten, e_dialinginfo.number);
816 // if (strchr(exten, ','))
817 // *strchr(exten, ',') = '\0';
818 // if (!read_extension(&e_ext, exten))
819 if (!read_extension(&e_ext, e_dialinginfo.number))
821 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) extension %s not configured\n", ea_endpoint->ep_serial, e_dialinginfo.number);
822 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_OUTOFORDER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
823 return; /* must exit here */
826 if (e_dialinginfo.itype == INFO_ITYPE_VBOX)
828 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing directly to VBOX\n", ea_endpoint->ep_serial);
833 /* string from unconditional call forward (cfu) */
837 /* present to forwarded party */
838 if (e_ext.anon_ignore && e_callerinfo.id[0])
840 e_callerinfo.present = INFO_PRESENT_ALLOWED;
842 if (!!strcmp(p, "vbox") || (e_capainfo.bearer_capa==INFO_BC_AUDIO) || (e_capainfo.bearer_capa==INFO_BC_SPEECH))
846 /* string from busy call forward (cfb) */
850 class EndpointAppPBX *checkapp = apppbx_first;
853 if (checkapp != this) /* any other endpoint except our own */
855 if (!strcmp(checkapp->e_terminal, e_terminal))
857 /* present to forwarded party */
858 if (e_ext.anon_ignore && e_callerinfo.id[0])
860 e_callerinfo.present = INFO_PRESENT_ALLOWED;
862 if (!!strcmp(p, "vbox") || (e_capainfo.bearer_capa==INFO_BC_AUDIO) || (e_capainfo.bearer_capa==INFO_BC_SPEECH))
866 checkapp = checkapp->next;
870 /* string from no-response call forward (cfnr) */
874 /* when cfnr is done, out_setup() will setup the call */
877 /* present to forwarded party */
878 if (e_ext.anon_ignore && e_callerinfo.id[0])
880 e_callerinfo.present = INFO_PRESENT_ALLOWED;
884 if (!!strcmp(p, "vbox") || (e_capainfo.bearer_capa==INFO_BC_AUDIO) || (e_capainfo.bearer_capa==INFO_BC_SPEECH))
886 e_cfnr_release = now + e_ext.cfnr_delay;
887 e_cfnr_call = now + e_ext.cfnr_delay + 1; /* call one second after release */
888 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) setting time for call-forward-busy to %s with delay %ld.\n", ea_endpoint->ep_serial, e_ext.cfnr, e_ext.cfnr_delay);
892 /* call to all internal interfaces */
893 p = e_ext.interfaces;
894 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) generating multiple calls for extension %s to interfaces %s\n", ea_endpoint->ep_serial, e_dialinginfo.number, p);
898 while(*p!=',' && *p!='\0')
903 /* found interface */
904 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) calling to interface %s\n", ea_endpoint->ep_serial, ifname);
905 /* hunt for mISDNport and create Port */
906 mISDNport = hunt_port(ifname, &channel);
909 printlog("%3d endpoint INTERFACE '%s' not found or busy\n", ea_endpoint->ep_serial, ifname);
910 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) given interface: '%s' not found or too busy to accept calls.\n", ea_endpoint->ep_serial, e_ext.interfaces);
913 /* creating INTERNAL port */
914 SPRINT(portname, "%s-%d-out", mISDNport->interface_name, mISDNport->portnum);
915 port = new Pdss1((mISDNport->ntmode)?PORT_TYPE_DSS1_NT_OUT:PORT_TYPE_DSS1_TE_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport.channel_force);
918 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) port '%s' failed to create\n", ea_endpoint->ep_serial, mISDNport->interface_name);
919 goto check_anycall_intern;
921 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) got port %s\n", ea_endpoint->ep_serial, port->p_name);
922 memset(&dialinginfo, 0, sizeof(dialinginfo));
923 SCPY(dialinginfo.number, e_dialinginfo.number);
924 dialinginfo.itype = INFO_ITYPE_INTERN;
925 dialinginfo.ntype = e_dialinginfo.ntype;
926 /* create port_list relation */
927 portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type);
930 PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
932 goto check_anycall_intern;
935 if (e_callerinfo.id[0] && (e_ext.centrex || e_ext.display_name))
937 dirname = parse_directory(e_callerinfo.id, e_callerinfo.ntype);
939 SCPY(e_callerinfo.name, dirname);
941 // dss1 = (class Pdss1 *)port;
943 //printf("INTERNAL caller=%s,id=%s,dial=%s\n", param.setup.networkid, param.setup.callerinfo.id, param.setup.dialinginfo.number);
944 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_SETUP);
945 memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
946 memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
947 memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
948 memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
949 //terminal SCPY(message->param.setup.from_terminal, e_terminal);
950 //terminal if (e_dialinginfo.number)
951 //terminal SCPY(message->param.setup.to_terminal, e_dialinginfo.number);
952 /* handle restricted caller ids */
953 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);
954 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);
955 /* display callerid if desired for extension */
956 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));
957 //printf("\n\ndisplay = %s\n\n\n",message->param.setup.callerinfo.display);
958 /* use cnip, if enabld */
960 message->param.setup.callerinfo.name[0] = '\0';
961 /* screen clip if prefix is required */
962 if (message->param.setup.callerinfo.id[0] && e_ext.clip_prefix[0])
964 SCPY(message->param.setup.callerinfo.id, e_ext.clip_prefix);
965 SCAT(message->param.setup.callerinfo.id, numberrize_callerinfo(e_callerinfo.id,e_callerinfo.ntype));
966 message->param.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
968 /* use internal caller id */
969 if (e_callerinfo.intern[0] && (message->param.setup.callerinfo.present!=INFO_PRESENT_RESTRICTED || e_ext.anon_ignore))
971 SCPY(message->param.setup.callerinfo.id, e_callerinfo.intern);
972 message->param.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
974 message_put(message);
979 /* string from parallel call forward (cfp) */
983 if (e_ext.anon_ignore && e_callerinfo.id[0])
985 e_callerinfo.present = INFO_PRESENT_ALLOWED;
989 vbox_only: /* entry point for answering machine only */
990 cfu_only: /* entry point for cfu */
991 cfb_only: /* entry point for cfb */
992 cfnr_only: /* entry point for cfnr */
993 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call extension %s for external destiantion(s) '%s'\n", ea_endpoint->ep_serial, e_dialinginfo.number, p);
997 /* only if vbox should be dialed, and terminal is given */
998 if (!strcmp(p, "vbox") && e_terminal[0])
1000 /* go to the end of p */
1003 /* answering vbox call */
1004 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) answering machine\n", ea_endpoint->ep_serial);
1006 if (!(port = new VBoxPort(PORT_TYPE_VBOX_OUT, &port_settings)))
1008 PERROR("EPOINT(%d) no mem for port\n", ea_endpoint->ep_serial);
1011 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) allocated port %s\n", ea_endpoint->ep_serial, port->p_name);
1012 UCPY(cfp, e_terminal); /* cfp or any other direct forward/vbox */
1016 while(*p!=',' && *p!='\0')
1022 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cfp external %s\n", ea_endpoint->ep_serial, cfp);
1023 /* hunt for mISDNport and create Port */
1024 mISDNport = mISDNport_first;
1028 /* check for external or given interface */
1029 if (((!e_dialinginfo.interfaces[0])&&mISDNport->iftype==IF_EXTERN) || !strcmp(mISDNport->interface_name, e_dialinginfo.interfaces))
1031 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) interface '%s' found\n", ea_endpoint->ep_serial, mISDNport->interface_name);
1032 cause = CAUSE_NOCHANNEL; /* when failing: out of channels */
1033 /* if PTP, skip all down links */
1034 if (mISDNport->ptp && !mISDNport->l2link)
1036 printlog("%3d endpoint INTERFACE Layer 2 of interface '%s' is down.\n", ea_endpoint->ep_serial, mISDNport->interface_name);
1037 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) skipping because it is PTP with L2 down\n", ea_endpoint->ep_serial);
1038 mISDNport = mISDNport->next;
1041 /* if no channel is available */
1042 if (mISDNport->multilink || !mISDNport->ntmode || mISDNport->ptp)
1046 ii = mISDNport->b_num;
1049 if (mISDNport->b_state[i])
1053 if (use >= mISDNport->b_num)
1055 printlog("%3d endpoint INTERFACE Interface '%s' has no free channel.\n", ea_endpoint->ep_serial, mISDNport->interface_name);
1056 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);
1057 mISDNport = mISDNport->next;
1061 /* found interface */
1062 printlog("%3d endpoint INTERFACE Interface '%s' found for external call.\n", ea_endpoint->ep_serial, mISDNport->interface_name);
1065 mISDNport = mISDNport->next;
1069 /* creating EXTERNAL port*/
1070 SPRINT(portname, "%s-%d-out", mISDNport->interface_name, mISDNport->portnum);
1071 port = new Pdss1((mISDNport->ntmode)?PORT_TYPE_DSS1_NT_OUT:PORT_TYPE_DSS1_TE_OUT, mISDNport, portname, &port_settings);
1075 printlog("%3d endpoint INTERFACE External interface not found or busy.\n", ea_endpoint->ep_serial);
1076 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");
1081 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) no port found or created, which is idle.\n", ea_endpoint->ep_serial);
1082 goto check_anycall_intern;
1084 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) found or created port %s\n", ea_endpoint->ep_serial, port->p_name);
1085 memset(&dialinginfo, 0, sizeof(dialinginfo));
1086 SCPY(dialinginfo.number, cfp);
1087 dialinginfo.itype = INFO_ITYPE_EXTERN;
1088 dialinginfo.ntype = e_dialinginfo.ntype;
1089 portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type);
1092 PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
1094 goto check_anycall_intern;
1096 //printf("EXTERNAL caller=%s,id=%s,dial=%s\n", param.setup.networkid, param.setup.callerinfo.id, param.setup.dialinginfo.number);
1097 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_SETUP);
1098 memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
1099 memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
1100 memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
1101 /* if clip is hidden */
1102 if (e_ext.clip==CLIP_HIDE && port->p_type!=PORT_TYPE_VBOX_OUT)
1104 SCPY(message->param.setup.callerinfo.id, e_ext.callerid);
1105 SCPY(message->param.setup.callerinfo.intern, e_terminal);
1106 message->param.setup.callerinfo.ntype = e_ext.callerid_type;
1107 message->param.setup.callerinfo.present = e_ext.callerid_present;
1109 memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
1110 //terminal SCPY(message->param.setup.from_terminal, e_terminal);
1111 //terminal if (e_dialinginfo.number)
1112 //terminal SCPY(message->param.setup.to_terminal, e_dialinginfo.number);
1113 /* handle restricted caller ids */
1114 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);
1115 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);
1116 /* display callerid if desired for extension */
1117 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));
1118 message_put(message);
1119 logmessage(message);
1123 check_anycall_intern:
1124 /* now we have all ports created */
1127 printlog("%3d endpoint INTERFACE No port or no parallel forwarding defined. Nothing to call to.\n", ea_endpoint->ep_serial);
1128 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) no port or no cfp defined for extension, nothing to dial.\n", ea_endpoint->ep_serial);
1129 if (!ea_endpoint->ep_call_id)
1131 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
1132 return; /* must exit here */
1137 /* *********************** h323 call */
1138 case INFO_ITYPE_H323:
1139 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing H323: '%s'\n", ea_endpoint->ep_serial, e_dialinginfo.number);
1142 if (!(port = new H323Port(PORT_TYPE_H323_OUT, "H323-out", &port_settings)))
1144 PERROR("EPOINT(%d) no mem for port\n", ea_endpoint->ep_serial);
1147 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) allocated port %s\n", ea_endpoint->ep_serial, port->p_name);
1148 memset(&dialinginfo, 0, sizeof(dialinginfo));
1149 SCPY(dialinginfo.number, e_dialinginfo.number);
1150 dialinginfo.itype = INFO_ITYPE_H323;
1151 dialinginfo.ntype = e_dialinginfo.ntype;
1152 portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type);
1155 PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
1157 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
1160 //printf("INTERNAL caller=%s,id=%s,dial=%s\n", param.setup.networkid, param.setup.callerinfo.id, param.setup.dialinginfo.number);
1161 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_SETUP);
1162 memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
1163 memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
1164 memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
1165 memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
1166 //terminal SCPY(message->param.setup.from_terminal, e_terminal);
1167 //terminal if (e_dialinginfo.number)
1168 //terminal SCPY(message->param.setup.to_terminal, e_dialinginfo.number);
1169 /* handle restricted caller ids */
1170 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);
1171 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);
1172 /* display callerid if desired for extension */
1173 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));
1174 message_put(message);
1175 logmessage(message);
1179 /* *********************** sip call */
1180 case INFO_ITYPE_SIP:
1181 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing SIP: '%s'\n", ea_endpoint->ep_serial, e_dialinginfo.number);
1184 if (!(port = new Psip(PORT_TYPE_SIP_OUT, 0, 0, e_dialinginfo.number)))
1186 PERROR("EPOINT(%d) no mem for port\n", ea_endpoint->ep_serial);
1189 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) allocated port %s\n", ea_endpoint->ep_serial, port->p_name);
1190 memset(&dialinginfo, 0, sizeof(dialinginfo));
1191 SCPY(dialinginfo.number, e_dialinginfo.number);
1192 dialinginfo.itype = INFO_ITYPE_SIP;
1193 dialinginfo.ntype = e_dialinginfo.ntype;
1194 portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type);
1197 PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
1199 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
1202 //printf("INTERNAL caller=%s,id=%s,dial=%s\n", param.setup.networkid, param.setup.callerinfo.id, param.setup.dialinginfo.number);
1203 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_SETUP);
1204 memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
1205 memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
1206 memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
1207 memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
1208 //terminal SCPY(message->param.setup.from_terminal, e_terminal);
1209 //terminal if (e_dialinginfo.number)
1210 //terminal SCPY(message->param.setup.to_terminal, e_dialinginfo.number);
1211 /* handle restricted caller ids */
1212 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);
1213 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);
1214 /* display callerid if desired for extension */
1215 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));
1216 message_put(message);
1217 logmessage(message);
1221 /* *********************** external call */
1223 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing external: '%s'\n", ea_endpoint->ep_serial, e_dialinginfo.number);
1224 /* call to extenal interfaces */
1225 p = e_dialinginfo.number;
1229 while(*p!=',' && *p!='\0')
1230 SCCAT(number, *p++);
1234 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");
1235 /* hunt for mISDNport and create Port */
1236 mISDNport = mISDNport_first;
1240 /* check for external or given interface */
1241 if ((!e_dialinginfo.interfaces[0]&&mISDNport->iftype==IF_EXTERN) || !strcmp(mISDNport->interface_name, e_dialinginfo.interfaces))
1243 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) interface '%s' found\n", ea_endpoint->ep_serial, mISDNport->interface_name);
1244 cause = CAUSE_NOCHANNEL; /* when failing: out of channels */
1245 /* if PTP, skip all down links */
1246 if (mISDNport->ptp && !mISDNport->l2link)
1248 printlog("%3d endpoint INTERFACE Layer 2 of interface '%s' is down.\n", ea_endpoint->ep_serial, mISDNport->interface_name);
1249 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) skipping because it is PTP with L2 down\n", ea_endpoint->ep_serial);
1250 mISDNport = mISDNport->next;
1253 /* if no channel is available */
1254 if (mISDNport->multilink || !mISDNport->ntmode || mISDNport->ptp)
1258 ii = mISDNport->b_num;
1261 if (mISDNport->b_state[i])
1265 if (use >= mISDNport->b_num)
1267 printlog("%3d endpoint INTERFACE Interface '%s' has no free channel.\n", ea_endpoint->ep_serial, mISDNport->interface_name);
1268 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);
1269 mISDNport = mISDNport->next;
1273 /* found interface */
1274 printlog("%3d endpoint INTERFACE Interface '%s' found for external call.\n", ea_endpoint->ep_serial, mISDNport->interface_name);
1277 mISDNport = mISDNport->next;
1281 printlog("%3d endpoint INTERFACE External interface not found or busy.\n", ea_endpoint->ep_serial);
1282 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");
1283 goto check_anycall_extern;
1285 /* creating EXTERNAL port*/
1286 SPRINT(portname, "%s-%d-out", mISDNport->interface_name, mISDNport->portnum);
1287 port = new Pdss1((mISDNport->ntmode)?PORT_TYPE_DSS1_NT_OUT:PORT_TYPE_DSS1_TE_OUT, mISDNport, portname, &port_settings);
1290 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) no external port available\n", ea_endpoint->ep_serial);
1291 goto check_anycall_extern;
1293 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) created port %s\n", ea_endpoint->ep_serial, port->p_name);
1294 memset(&dialinginfo, 0, sizeof(dialinginfo));
1295 SCPY(dialinginfo.number, number);
1296 dialinginfo.itype = INFO_ITYPE_EXTERN;
1297 dialinginfo.ntype = e_dialinginfo.ntype;
1298 portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type);
1301 PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
1303 goto check_anycall_extern;
1305 // dss1 = (class Pdss1 *)port;
1306 //printf("EXTERNAL caller=%s,id=%s,dial=%s\n", param.setup.networkid, param.setup.callerinfo.id, param.setup.dialinginfo.number);
1307 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_SETUP);
1308 memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
1309 SCPY(message->param.setup.dialinginfo.number, number);
1310 memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
1311 memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
1312 memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
1313 //terminal SCPY(message->param.setup.from_terminal, e_terminal);
1314 //terminal if (e_dialinginfo.number)
1315 //terminal SCPY(message->param.setup.to_terminal, e_dialinginfo.number);
1316 /* handle restricted caller ids */
1317 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);
1318 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);
1319 /* display callerid if desired for extension */
1320 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));
1321 message_put(message);
1322 logmessage(message);
1326 check_anycall_extern:
1327 /* now we have all ports created */
1330 printlog("%3d endpoint INTERFACE No free port found for making any call.\n", ea_endpoint->ep_serial);
1331 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) no port found which is idle for at least one number\n", ea_endpoint->ep_serial);
1332 if (!ea_endpoint->ep_call_id)
1334 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOCHANNEL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
1335 return; /* must exit here */
1343 /* handler for endpoint
1347 int EndpointAppPBX::handler(void)
1349 if (e_crypt_state!=CM_ST_NULL)
1354 /* process answering machine (play) handling */
1357 if (e_action->index == ACTION_VBOX_PLAY)
1360 /* process action timeout */
1361 if (e_action_timeout)
1362 if (now_d >= e_action_timeout)
1364 if (e_state!=EPOINT_STATE_CONNECT)
1367 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) current action timed out.\n", ea_endpoint->ep_serial);
1368 e_multipoint_cause = CAUSE_NOUSER;
1369 e_multipoint_location = LOCATION_PRIVATE_LOCAL;
1370 new_state(EPOINT_STATE_IN_OVERLAP);
1373 return(1); /* we must exit, because our endpoint might be gone */
1375 e_action_timeout = 0;
1378 /* process action timeout */
1379 if (e_match_timeout)
1380 if (now_d >= e_match_timeout)
1383 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) we got a match timeout.\n", ea_endpoint->ep_serial);
1385 return(1); /* we must exit, because our endpoint might be gone */
1390 /* process redialing (epoint redials to port) */
1393 if (now_d >= e_redial)
1396 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) starting redial.\n", ea_endpoint->ep_serial);
1398 new_state(EPOINT_STATE_OUT_SETUP);
1399 /* call special setup routine */
1406 /* process powerdialing (epoint redials to epoint) */
1407 if (e_powerdialing > 0)
1409 if (now_d >= e_powerdialing)
1411 e_powerdialing = -1; /* leave power dialing on */
1412 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) starting redial of powerdial.\n", ea_endpoint->ep_serial);
1415 e_ruleset = ruleset_main;
1417 e_rule = e_ruleset->rule_first;
1419 new_state(EPOINT_STATE_IN_OVERLAP);
1425 /* process call forward no response */
1428 struct port_list *portlist;
1429 struct message *message;
1431 if (now >= e_cfnr_release)
1433 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call-forward-no-response time has expired, hanging up.\n", ea_endpoint->ep_serial);
1436 /* release all ports */
1437 while((portlist = ea_endpoint->ep_portlist))
1439 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_RELEASE);
1440 message->param.disconnectinfo.cause = CAUSE_NORMAL; /* normal clearing */
1441 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1442 message_put(message);
1443 logmessage(message);
1444 ea_endpoint->free_portlist(portlist);
1447 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
1448 message->param.channel = CHANNEL_STATE_HOLD;
1449 message_put(message);
1450 /* indicate no patterns */
1451 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_NOPATTERN);
1452 message_put(message);
1453 /* set setup state, since we have no response from the new call */
1454 new_state(EPOINT_STATE_OUT_SETUP);
1459 if (now >= e_cfnr_call)
1461 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call-forward-busy time has expired, calling the forwarded number: %s.\n", ea_endpoint->ep_serial, e_ext.cfnr);
1467 /* handle connection to user */
1468 if (e_state == EPOINT_STATE_IDLE)
1470 /* epoint is idle, check callback */
1472 if (now_d >= e_callback)
1474 e_callback = 0; /* done with callback */
1475 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) starting callback.\n", ea_endpoint->ep_serial);
1476 new_state(EPOINT_STATE_OUT_SETUP);
1482 /* check for password timeout */
1484 if (e_action->index==ACTION_PASSWORD || e_action->index==ACTION_PASSWORD_WRITE)
1486 struct port_list *portlist;
1488 if (now >= e_password_timeout)
1490 e_ruleset = ruleset_main;
1492 e_rule = e_ruleset->rule_first;
1494 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) password timeout %s\n", ea_endpoint->ep_serial, e_extdialing);
1495 printlog("%3d endpoint PASSWORD timeout\n", ea_endpoint->ep_serial);
1496 e_connectedmode = 0;
1498 new_state(EPOINT_STATE_OUT_DISCONNECT);
1499 portlist = ea_endpoint->ep_portlist;
1502 message_disconnect_port(portlist, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, "");
1503 set_tone(portlist, "cause_10");
1513 /* doing a hookflash */
1514 void EndpointAppPBX::hookflash(void)
1518 /* be sure that we are active */
1520 e_tx_state = NOTIFY_STATE_ACTIVE;
1522 printlog("%3d endpoint HOOKFLASH\n", ea_endpoint->ep_serial);
1523 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dtmf hookflash detected.\n", ea_endpoint->ep_serial);
1524 if (ea_endpoint->ep_use > 1)
1526 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot hooflash while child process is running.\n", ea_endpoint->ep_serial);
1529 /* dialtone after pressing the hash key */
1530 process_hangup(e_call_cause, e_call_location);
1531 e_multipoint_cause = CAUSE_NOUSER;
1532 e_multipoint_location = LOCATION_PRIVATE_LOCAL;
1533 port = find_port_id(ea_endpoint->ep_portlist->port_id);
1536 port->set_echotest(0);
1538 if (ea_endpoint->ep_call_id)
1540 release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
1542 e_ruleset = ruleset_main;
1544 e_rule = e_ruleset->rule_first;
1546 new_state(EPOINT_STATE_IN_OVERLAP);
1547 e_connectedmode = 1;
1548 SCPY(e_dialinginfo.number, e_ext.prefix);
1549 e_extdialing = e_dialinginfo.number;
1551 if (e_dialinginfo.number[0])
1553 set_tone(ea_endpoint->ep_portlist, "dialing");
1557 set_tone(ea_endpoint->ep_portlist, "dialpbx");
1564 /* messages from port
1566 /* port MESSAGE_SETUP */
1567 void EndpointAppPBX::port_setup(struct port_list *portlist, int message_type, union parameter *param)
1569 struct message *message;
1571 struct interface *interface;
1573 char extension1[32];
1575 int writeext; /* flags need to write extension after modification */
1578 portlist->port_type = param->setup.port_type;
1579 memcpy(&e_callerinfo, ¶m->setup.callerinfo, sizeof(e_callerinfo));
1580 memcpy(&e_dialinginfo, ¶m->setup.dialinginfo, sizeof(e_dialinginfo));
1581 memcpy(&e_redirinfo, ¶m->setup.redirinfo, sizeof(e_redirinfo));
1582 memcpy(&e_capainfo, ¶m->setup.capainfo, sizeof(e_capainfo));
1583 e_dtmf = param->setup.dtmf;
1585 /* check where the call is from */
1586 if ((param->setup.port_type&PORT_CLASS_mISDN_MASK) == PORT_CLASS_mISDN_DSS1)
1588 interface = interface_first;
1591 if (param->setup.isdn_port>=0 && param->setup.isdn_port<(int)sizeof(interface->ports))
1593 if (interface->ports[param->setup.isdn_port])
1596 interface = interface->next;
1600 /* interface is known */
1601 if (interface->iftype==IF_INTERN)
1603 /* interface is internal */
1604 if (interface->extensions[0])
1606 /* extensions are assigned to interface */
1607 p = interface->extensions;
1608 extension1[0] = '\0';
1611 extension[0] = '\0';
1612 while(*p!=',' && *p!='\0')
1613 SCCAT(extension, *p++);
1617 SCPY(extension1, extension);
1618 if (!strcmp(extension, e_callerinfo.id))
1620 extension[0] = '\0'; /* NOTE: empty if we did not find */
1624 /* id was found at extension's list */
1625 e_callerinfo.itype = INFO_ITYPE_INTERN;
1626 SCPY(e_callerinfo.intern, extension);
1630 /* if was provided by default */
1631 e_callerinfo.itype = INFO_ITYPE_INTERN;
1632 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);
1633 SCPY(e_callerinfo.intern, extension1);
1637 /* no extension given, so we use the caller id */
1638 e_callerinfo.itype = INFO_ITYPE_INTERN;
1639 SCPY(e_callerinfo.intern, e_callerinfo.id);
1643 /* interface is external */
1644 e_callerinfo.intern[0] = '\0';
1648 /* interface is unknown */
1649 message_disconnect_port(portlist, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, "");
1650 new_state(EPOINT_STATE_OUT_DISCONNECT);
1651 set_tone(portlist, "cause_80"); /* pbx cause: extension not authorized */
1652 e_terminal[0] = '\0'; /* no terminal */
1657 if (e_callerinfo.itype == INFO_ITYPE_INTERN)
1659 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming call is internal\n", ea_endpoint->ep_serial);
1660 /* port makes call from extension */
1661 SCPY(e_callerinfo.id, e_callerinfo.intern);
1662 SCPY(e_terminal, e_callerinfo.intern);
1663 SCPY(e_terminal_interface, e_callerinfo.interface);
1666 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming call is external or voip\n", ea_endpoint->ep_serial);
1668 printlog("%3d incoming %s='%s'%s%s%s%s dialing='%s'\n",
1669 ea_endpoint->ep_serial,
1670 (e_callerinfo.intern[0])?"SETUP from intern":"SETUP from extern",
1671 (e_callerinfo.intern[0])?e_callerinfo.intern:e_callerinfo.id,
1672 (e_callerinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
1673 (e_redirinfo.id[0])?"redirected='":"",
1675 (e_redirinfo.id[0])?"'":"",
1676 e_dialinginfo.number
1679 if (e_callerinfo.itype == INFO_ITYPE_INTERN)
1681 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call from extension '%s'\n", ea_endpoint->ep_serial, e_terminal);
1683 /* get extension's info about caller */
1684 if (!read_extension(&e_ext, e_terminal))
1686 /* extension doesn't exist */
1687 printlog("%3d endpoint EXTENSION '%s' doesn't exist, please check or create.\n", ea_endpoint->ep_serial, e_callerinfo.id);
1688 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) rejecting call from not existing extension: '%s'\n", ea_endpoint->ep_serial, e_terminal);
1689 message_disconnect_port(portlist, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, "");
1690 new_state(EPOINT_STATE_OUT_DISCONNECT);
1691 set_tone(portlist, "cause_80"); /* pbx cause: extension not authorized */
1692 e_terminal[0] = '\0'; /* no terminal */
1697 /* put prefix (next) in front of e_dialinginfo.number */
1700 SPRINT(buffer, "%s%s", e_ext.next, e_dialinginfo.number);
1701 SCPY(e_dialinginfo.number, buffer);
1702 e_ext.next[0] = '\0';
1704 } else if (e_ext.prefix[0])
1706 SPRINT(buffer, "%s%s", e_ext.prefix, e_dialinginfo.number);
1707 SCPY(e_dialinginfo.number, buffer);
1710 /* screen caller id */
1711 e_callerinfo.screen = INFO_SCREEN_NETWORK;
1713 SCPY(e_callerinfo.name, e_ext.name);
1714 /* use caller id (or if exist: id_next_call) for this call */
1715 if (e_ext.id_next_call_present >= 0)
1717 SCPY(e_callerinfo.id, e_ext.id_next_call);
1718 /* if we restrict the pesentation */
1719 if (e_ext.id_next_call_present==INFO_PRESENT_ALLOWED && e_callerinfo.present==INFO_PRESENT_RESTRICTED)
1720 e_callerinfo.present = INFO_PRESENT_RESTRICTED;
1721 else e_callerinfo.present = e_ext.id_next_call_present;
1722 e_callerinfo.ntype = e_ext.id_next_call_type;
1723 e_ext.id_next_call_present = -1;
1727 SCPY(e_callerinfo.id, e_ext.callerid);
1728 /* if we restrict the pesentation */
1729 if (e_ext.callerid_present==INFO_PRESENT_ALLOWED && e_callerinfo.present==INFO_PRESENT_RESTRICTED)
1730 e_callerinfo.present = INFO_PRESENT_RESTRICTED;
1731 else e_callerinfo.present = e_ext.callerid_present;
1732 e_callerinfo.ntype = e_ext.callerid_type;
1735 /* extension is written */
1737 write_extension(&e_ext, e_terminal);
1739 /* set volume of rx and tx */
1740 if (param->setup.callerinfo.itype == INFO_ITYPE_INTERN)
1741 if (e_ext.txvol!=256 || e_ext.rxvol!=256)
1743 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_mISDNSIGNAL);
1744 message->param.mISDNsignal.message = mISDNSIGNAL_VOLUME;
1745 message->param.mISDNsignal.rxvol = e_ext.txvol;
1746 message->param.mISDNsignal.txvol = e_ext.rxvol;
1747 message_put(message);
1750 /* start recording if enabled */
1751 if (e_ext.record!=CODEC_OFF && (e_capainfo.bearer_capa==INFO_BC_SPEECH || e_capainfo.bearer_capa==INFO_BC_AUDIO))
1753 /* check if we are a terminal */
1754 if (e_terminal[0] == '\0')
1755 PERROR("Port(%d) cannot record because we are not a terminal\n", ea_endpoint->ep_serial);
1758 port = find_port_id(portlist->port_id);
1760 port->open_record(e_ext.record, 0, 0, e_terminal, e_ext.anon_ignore, "", 0);
1765 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call from external port\n", ea_endpoint->ep_serial);
1766 /* no terminal identification */
1767 e_terminal[0] = '\0';
1768 e_terminal_interface[0] = '\0';
1769 memset(&e_ext, 0, sizeof(e_ext));
1770 e_ext.rights = 4; /* right to dial internat */
1774 e_ruleset = ruleset_main;
1776 e_rule = e_ruleset->rule_first;
1778 e_extdialing = e_dialinginfo.number;
1779 new_state(EPOINT_STATE_IN_SETUP);
1780 if (e_dialinginfo.number[0])
1782 set_tone(portlist, "dialing");
1786 set_tone(portlist, "dialpbx");
1788 set_tone(portlist, "dialtone");
1791 if (e_state == EPOINT_STATE_IN_SETUP)
1793 /* request MORE info, if not already at higher state */
1794 new_state(EPOINT_STATE_IN_OVERLAP);
1795 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_OVERLAP);
1796 message_put(message);
1797 logmessage(message);
1801 /* port MESSAGE_INFORMATION */
1802 void EndpointAppPBX::port_information(struct port_list *portlist, int message_type, union parameter *param)
1804 printlog("%3d incoming INFORMATION information='%s'\n",
1805 ea_endpoint->ep_serial,
1806 param->information.number
1810 /* turn off dtmf detection, in case dtmf is sent with keypad information */
1813 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);
1817 /* if vbox_play is done, the information are just used as they come */
1819 if (e_action->index == ACTION_VBOX_PLAY)
1821 /* concat dialing string */
1822 SCAT(e_dialinginfo.number, param->information.number);
1827 /* keypad when disconnect but in connected mode */
1828 if (e_state==EPOINT_STATE_OUT_DISCONNECT && e_connectedmode)
1830 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) keypad information received after disconnect: %s.\n", ea_endpoint->ep_serial, param->information.number);
1831 /* processing keypad function */
1832 if (param->information.number[0] == '0')
1839 /* keypad when connected */
1840 if (e_state == EPOINT_STATE_CONNECT && e_ext.keypad)
1842 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) keypad information received during connect: %s.\n", ea_endpoint->ep_serial, param->information.number);
1843 /* processing keypad function */
1844 if (param->information.number[0] == '0')
1848 if (param->information.number[0])
1849 keypad_function(param->information.number[0]);
1852 if (e_state != EPOINT_STATE_IN_OVERLAP)
1854 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in overlap, or connect state.\n", ea_endpoint->ep_serial);
1857 if (!param->information.number[0])
1859 if (e_dialinginfo.number[0]=='\0' && !e_action)
1861 set_tone(portlist, "dialing");
1864 if (e_action->index==ACTION_OUTDIAL
1865 || e_action->index==ACTION_EXTERNAL)
1868 set_tone(portlist, "dialing");
1869 else if (!e_extdialing[0])
1870 set_tone(portlist, "dialing");
1872 /* concat dialing string */
1873 SCAT(e_dialinginfo.number, param->information.number);
1877 /* port MESSAGE_DTMF */
1878 void EndpointAppPBX::port_dtmf(struct port_list *portlist, int message_type, union parameter *param)
1880 printlog("%3d incoming DTMF digit='%c'\n",
1881 ea_endpoint->ep_serial,
1884 /* only if dtmf detection is enabled */
1887 PDEBUG(DEBUG_EPOINT, "dtmf detection is disabled\n");
1892 NOTE: vbox is now handled due to overlap state
1893 /* if vbox_play is done, the dtmf digits are just used as they come */
1895 if (e_action->index == ACTION_VBOX_PLAY)
1897 /* concat dialing string */
1898 if (strlen(e_dialinginfo.number)+1 < sizeof(e_dialinginfo.number))
1900 e_dialinginfo.number[strlen(e_dialinginfo.number)+1] = '\0';
1901 e_dialinginfo.number[strlen(e_dialinginfo.number)] = param->dtmf;
1904 /* continue to process *X# sequences */
1908 /* check for *X# sequence */
1909 if (e_state == EPOINT_STATE_CONNECT)
1911 if (e_dtmf_time+3 < now)
1913 /* the last digit was too far in the past to be a sequence */
1914 if (param->dtmf == '*')
1915 /* only start is allowed in the sequence */
1921 /* we have a sequence of digits, see what we got */
1922 if (param->dtmf == '*')
1924 else if (param->dtmf>='0' && param->dtmf<='9')
1926 /* we need to have a star before we receive the digit of the sequence */
1927 if (e_dtmf_last == '*')
1928 e_dtmf_last = param->dtmf;
1929 } else if (param->dtmf == '#')
1932 if (e_dtmf_last>='0' && e_dtmf_last<='9')
1934 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dtmf sequence *%c# detected.\n", ea_endpoint->ep_serial, e_dtmf_last);
1935 if (e_dtmf_last == '0')
1940 /* processing keypad function */
1942 keypad_function(e_dtmf_last);
1948 /* set last time of dtmf */
1953 /* check for ## hookflash during dialing */
1955 if (e_action->index==ACTION_PASSWORD
1956 || e_action->index==ACTION_PASSWORD_WRITE)
1958 if (param->dtmf=='#') /* current digit is '#' */
1960 if (e_state==EPOINT_STATE_IN_DISCONNECT
1961 || (e_state!=EPOINT_STATE_CONNECT && e_dtmf_time+3>=now && e_dtmf_last=='#')) /* when disconnected, just #. when dialing, ##. */
1978 /* dialing using dtmf digit */
1979 if (e_state==EPOINT_STATE_IN_OVERLAP)// && e_state==e_connectedmode)
1981 if (e_dialinginfo.number[0]=='\0' && !e_action)
1983 set_tone(portlist, "dialing");
1985 /* concat dialing string */
1986 if (strlen(e_dialinginfo.number)+1 < sizeof(e_dialinginfo.number))
1988 e_dialinginfo.number[strlen(e_dialinginfo.number)+1] = '\0';
1989 e_dialinginfo.number[strlen(e_dialinginfo.number)] = param->dtmf;
1995 /* port MESSAGE_CRYPT */
1996 void EndpointAppPBX::port_crypt(struct port_list *portlist, int message_type, union parameter *param)
1998 /* send crypt response to cryptman */
1999 if (param->crypt.type == CR_MESSAGE_IND)
2000 cryptman_msg2man(param->crypt.data, param->crypt.len);
2002 cryptman_message(param->crypt.type, param->crypt.data, param->crypt.len);
2005 /* port MESSAGE_OVERLAP */
2006 void EndpointAppPBX::port_overlap(struct port_list *portlist, int message_type, union parameter *param)
2008 struct message *message;
2010 /* signal to call tool */
2011 admin_call_response(e_adminid, ADMIN_CALL_SETUP_ACK, "", 0, 0, 0);
2013 printlog("%3d incoming SETUP ACKNOWLEDGE\n",
2014 ea_endpoint->ep_serial
2016 if (e_dialing_queue[0] && portlist)
2018 /* send what we have not dialed yet, because we had no setup complete */
2019 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing pending digits: '%s'\n", ea_endpoint->ep_serial, e_dialing_queue);
2020 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_INFORMATION);
2021 SCPY(message->param.information.number, e_dialing_queue);
2022 message->param.information.ntype = INFO_NTYPE_UNKNOWN;
2023 message_put(message);
2024 logmessage(message);
2025 e_dialing_queue[0] = '\0';
2027 /* check if pattern is available */
2028 if (!ea_endpoint->ep_portlist->next && portlist->port_type==PORT_TYPE_DSS1_TE_OUT) /* one port_list relation and outgoing external*/
2030 /* indicate patterns */
2031 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_PATTERN);
2032 message_put(message);
2034 /* connect audio, if not already */
2035 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
2036 message->param.channel = CHANNEL_STATE_CONNECT;
2037 message_put(message);
2040 /* indicate no patterns */
2041 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_PATTERN);
2042 message_put(message);
2044 /* disconnect audio, if not already */
2045 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
2046 message->param.channel = CHANNEL_STATE_HOLD;
2047 message_put(message);
2049 new_state(EPOINT_STATE_OUT_OVERLAP);
2050 /* if we are in a call */
2051 if (ea_endpoint->ep_call_id)
2053 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, message_type);
2054 memcpy(&message->param, param, sizeof(union parameter));
2055 message_put(message);
2059 /* port MESSAGE_PROCEEDING */
2060 void EndpointAppPBX::port_proceeding(struct port_list *portlist, int message_type, union parameter *param)
2062 struct message *message;
2064 /* signal to call tool */
2065 admin_call_response(e_adminid, ADMIN_CALL_PROCEEDING, "", 0, 0, 0);
2067 printlog("%3d incoming PROCEEDING\n",
2068 ea_endpoint->ep_serial
2070 e_state = EPOINT_STATE_OUT_PROCEEDING;
2071 /* check if pattern is availatle */
2072 if (!ea_endpoint->ep_portlist->next && (portlist->port_type==PORT_TYPE_DSS1_TE_OUT || portlist->port_type==PORT_TYPE_VBOX_OUT)) /* one port_list relation and outgoing external*/
2074 /* indicate patterns */
2075 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_PATTERN);
2076 message_put(message);
2078 /* connect audio, if not already */
2079 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
2080 message->param.channel = CHANNEL_STATE_CONNECT;
2081 message_put(message);
2084 /* indicate no patterns */
2085 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_PATTERN);
2086 message_put(message);
2088 /* disconnect audio, if not already */
2089 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
2090 message->param.channel = CHANNEL_STATE_HOLD;
2091 message_put(message);
2093 /* if we are in a call */
2094 if (ea_endpoint->ep_call_id)
2096 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, message_type);
2097 memcpy(&message->param, param, sizeof(union parameter));
2098 message_put(message);
2102 /* port MESSAGE_ALERTING */
2103 void EndpointAppPBX::port_alerting(struct port_list *portlist, int message_type, union parameter *param)
2105 struct message *message;
2107 /* signal to call tool */
2108 admin_call_response(e_adminid, ADMIN_CALL_ALERTING, "", 0, 0, 0);
2110 printlog("%3d incoming ALERTING\n",
2111 ea_endpoint->ep_serial
2113 new_state(EPOINT_STATE_OUT_ALERTING);
2114 /* check if pattern is available */
2115 if (!ea_endpoint->ep_portlist->next && (portlist->port_type==PORT_TYPE_DSS1_TE_OUT || portlist->port_type==PORT_TYPE_VBOX_OUT)) /* one port_list relation and outgoing external*/
2117 /* indicate patterns */
2118 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_PATTERN);
2119 message_put(message);
2121 /* connect audio, if not already */
2122 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
2123 message->param.channel = CHANNEL_STATE_CONNECT;
2124 message_put(message);
2127 /* indicate no patterns */
2128 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_NOPATTERN);
2129 message_put(message);
2131 /* disconnect audio, if not already */
2132 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
2133 message->param.channel = CHANNEL_STATE_HOLD;
2134 message_put(message);
2136 /* if we are in a call */
2137 if (ea_endpoint->ep_call_id)
2139 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, message_type);
2140 memcpy(&message->param, param, sizeof(union parameter));
2141 message_put(message);
2145 /* port MESSAGE_CONNECT */
2146 void EndpointAppPBX::port_connect(struct port_list *portlist, int message_type, union parameter *param)
2148 struct message *message;
2150 unsigned long port_id = portlist->port_id;
2151 struct port_list *tportlist;
2154 /* signal to call tool */
2155 admin_call_response(e_adminid, ADMIN_CALL_CONNECT, numberrize_callerinfo(param->connectinfo.id,param->connectinfo.ntype), 0, 0, 0);
2157 memcpy(&e_connectinfo, ¶m->connectinfo, sizeof(e_connectinfo));
2158 printlog("%3d incoming CONNECT id='%s'%s\n",
2159 ea_endpoint->ep_serial,
2160 (e_connectinfo.intern[0])?e_connectinfo.intern:e_connectinfo.id,
2161 (e_connectinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":""
2163 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) removing all other ports (start)\n", ea_endpoint->ep_serial);
2164 while(ea_endpoint->ep_portlist->next) /* as long as we have at least two ports */
2166 tportlist = ea_endpoint->ep_portlist;
2167 if (tportlist->port_id == port_id) /* if the first portlist is the calling one, the second must be a different one */
2168 tportlist = tportlist->next;
2169 if (tportlist->port_id == port_id)
2171 PERROR("EPOINT(%d) software error: this should not happen since the portlist list must not have two links to the same port - exitting.\n");
2174 message = message_create(ea_endpoint->ep_serial, tportlist->port_id, EPOINT_TO_PORT, MESSAGE_RELEASE);
2175 message->param.disconnectinfo.cause = 26; /* non selected user clearing */
2176 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2177 message_put(message);
2178 logmessage(message);
2179 ea_endpoint->free_portlist(tportlist);
2181 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) removing all other ports (end)\n", ea_endpoint->ep_serial);
2185 /* screen connected name */
2187 SCPY(e_connectinfo.name, e_ext.name);
2189 /* add internal id to colp */
2190 SCPY(e_connectinfo.intern, e_terminal);
2192 /* we store the connected port number */
2193 SCPY(e_terminal_interface, e_connectinfo.interfaces);
2195 /* for internal and am calls, we get the extension's id */
2196 /* also for hidden calls to extension */
2197 if (portlist->port_type==PORT_TYPE_DSS1_NT_OUT || portlist->port_type==PORT_TYPE_VBOX_OUT || e_ext.colp==COLP_HIDE)
2199 SCPY(e_connectinfo.id, e_ext.callerid);
2200 SCPY(e_connectinfo.intern, e_terminal);
2201 e_connectinfo.itype = INFO_ITYPE_INTERN;
2202 e_connectinfo.ntype = e_ext.callerid_type;
2203 e_connectinfo.present = e_ext.callerid_present;
2205 if (portlist->port_type==PORT_TYPE_VBOX_OUT)
2207 e_connectinfo.itype = INFO_ITYPE_VBOX;
2208 e_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
2211 new_state(EPOINT_STATE_CONNECT);
2213 /* set volume of rx and tx */
2214 if (e_ext.txvol!=256 || e_ext.rxvol!=256)
2216 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_mISDNSIGNAL);
2217 message->param.mISDNsignal.message = mISDNSIGNAL_VOLUME;
2218 message->param.mISDNsignal.rxvol = e_ext.txvol;
2219 message->param.mISDNsignal.txvol = e_ext.rxvol;
2220 message_put(message);
2223 e_cfnr_call = e_cfnr_release = 0;
2225 e_dtmf = 1; /* allow dtmf */
2226 // if (call_countrelations(ea_endpoint->ep_call_id) == 2)
2229 /* other calls with no caller id (or not available for the extension) and force colp */
2230 if ((e_connectinfo.id[0]=='\0' || (e_connectinfo.present==INFO_PRESENT_RESTRICTED && !e_ext.anon_ignore))&& e_ext.colp==COLP_FORCE)
2232 e_connectinfo.present = INFO_PRESENT_NOTAVAIL;
2233 if (portlist->port_type==PORT_TYPE_DSS1_TE_OUT || portlist->port_type==PORT_TYPE_DSS1_NT_OUT) /* external extension answered */
2235 port = find_port_id(portlist->port_id);
2238 SCPY(e_connectinfo.id, nationalize_callerinfo(port->p_dialinginfo.number, &e_connectinfo.ntype));
2239 e_connectinfo.present = INFO_PRESENT_ALLOWED;
2242 if (portlist->port_type==PORT_TYPE_H323_OUT) /* h323 extension answered */
2244 SCPY(e_connectinfo.voip, port->p_dialinginfo.number);
2245 e_connectinfo.present = INFO_PRESENT_ALLOWED;
2246 // e_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
2248 if (portlist->port_type==PORT_TYPE_SIP_OUT) /* sip extension answered */
2250 SCPY(e_connectinfo.voip, port->p_dialinginfo.number);
2251 e_connectinfo.present = INFO_PRESENT_ALLOWED;
2252 // e_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
2255 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, message_type);
2256 memcpy(&message->param.connectinfo, &e_connectinfo, sizeof(struct connect_info));
2257 message_put(message);
2259 if (ea_endpoint->ep_call_id)
2261 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
2262 message->param.channel = CHANNEL_STATE_CONNECT;
2263 message_put(message);
2264 } else if (!e_adminid)
2267 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) we have a callback, so we create a call with cbcaller: \"%s\".\n", ea_endpoint->ep_serial, e_cbcaller);
2268 SCPY(e_terminal, e_cbcaller);
2269 new_state(EPOINT_STATE_IN_OVERLAP);
2270 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) callback from extension '%s'\n", ea_endpoint->ep_serial, e_terminal);
2272 /* get extension's info about terminal */
2273 if (!read_extension(&e_ext, e_terminal))
2275 /* extension doesn't exist */
2276 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) rejecting callback from not existing extension: '%s'\n", ea_endpoint->ep_serial, e_terminal);
2277 message_disconnect_port(portlist, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, "");
2278 new_state(EPOINT_STATE_OUT_DISCONNECT);
2279 set_tone(portlist, "cause_80"); /* pbx cause: extension not authorized */
2283 /* put prefix in front of e_cbdialing */
2284 SPRINT(buffer, "%s%s", e_ext.prefix, e_cbdialing);
2285 SCPY(e_dialinginfo.number, buffer);
2286 e_dialinginfo.itype = INFO_ITYPE_EXTERN;
2287 e_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
2289 /* use caller id (or if exist: id_next_call) for this call */
2290 e_callerinfo.screen = INFO_SCREEN_NETWORK;
2291 SCPY(e_callerinfo.intern, e_terminal);
2292 if (e_ext.id_next_call_present >= 0)
2294 SCPY(e_callerinfo.id, e_ext.id_next_call);
2295 e_callerinfo.present = e_ext.id_next_call_present;
2296 e_callerinfo.ntype = e_ext.id_next_call_type;
2297 e_ext.id_next_call_present = -1;
2298 /* extension is written */
2299 write_extension(&e_ext, e_terminal);
2302 SCPY(e_callerinfo.id, e_ext.callerid);
2303 e_callerinfo.present = e_ext.callerid_present;
2304 e_callerinfo.ntype = e_ext.callerid_type;
2307 e_connectedmode = 1; /* dtmf-hangup & disconnect prevention */
2310 /* check if caller id is NOT authenticated */
2311 if (!parse_callbackauth(e_terminal, &e_callbackinfo))
2313 /* make call state to enter password */
2314 new_state(EPOINT_STATE_IN_OVERLAP);
2315 e_action = &action_password_write;
2316 e_match_timeout = 0;
2317 e_match_to_action = NULL;
2318 e_dialinginfo.number[0] = '\0';
2319 e_extdialing = strchr(e_dialinginfo.number, '\0');
2320 e_password_timeout = now+20;
2324 /* incoming call (callback) */
2325 e_ruleset = ruleset_main;
2327 e_rule = e_ruleset->rule_first;
2329 e_extdialing = e_dialinginfo.number;
2330 if (e_dialinginfo.number[0])
2332 set_tone(portlist, "dialing");
2336 set_tone(portlist, "dialpbx");
2339 } else /* testcall */
2341 set_tone(portlist, "hold");
2344 /* start recording if enabled, not when answering machine answers */
2345 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))
2347 /* check if we are a terminal */
2348 if (e_terminal[0] == '\0')
2349 PERROR("Port(%d) cannot record because we are not a terminal\n", ea_endpoint->ep_serial);
2352 port = find_port_id(portlist->port_id);
2354 port->open_record(e_ext.record, 0, 0, e_terminal, e_ext.anon_ignore, "", 0);
2359 /* port MESSAGE_DISCONNECT MESSAGE_RELEASE */
2360 void EndpointAppPBX::port_disconnect_release(struct port_list *portlist, int message_type, union parameter *param)
2362 struct message *message;
2364 unsigned long port_id = portlist->port_id;
2368 /* signal to call tool */
2369 admin_call_response(e_adminid, (message_type==MESSAGE_DISCONNECT)?ADMIN_CALL_DISCONNECT:ADMIN_CALL_RELEASE, "", param->disconnectinfo.cause, param->disconnectinfo.location, 0);
2371 printlog("%3d incoming %s cause='%d' (%s) location='%d' (%s)\n",
2372 ea_endpoint->ep_serial,
2373 (message_type==MESSAGE_DISCONNECT)?"DISCONNECT":"RELEASE",
2374 param->disconnectinfo.cause,
2375 (param->disconnectinfo.cause>0 && param->disconnectinfo.cause<128)?isdn_cause[param->disconnectinfo.cause].english:"-",
2376 param->disconnectinfo.location,
2377 (param->disconnectinfo.location>=0 && param->disconnectinfo.location<16)?isdn_location[param->disconnectinfo.location].english:"-"
2380 //#warning does this work? only disconnect when incoming port hat not already disconnected yet?
2381 if (e_state==EPOINT_STATE_IN_DISCONNECT && message_type!=MESSAGE_RELEASE)// || e_state==EPOINT_STATE_OUT_DISCONNECT || e_state==EPOINT_STATE_IDLE)
2383 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are already disconnected.\n", ea_endpoint->ep_serial);
2388 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);
2389 if (param->disconnectinfo.cause == CAUSE_REJECTED) /* call rejected */
2391 e_multipoint_cause = CAUSE_REJECTED;
2392 e_multipoint_location = param->disconnectinfo.location;
2394 if (param->disconnectinfo.cause==CAUSE_NORMAL && e_multipoint_cause!=CAUSE_REJECTED) /* reject via hangup */
2396 e_multipoint_cause = CAUSE_NORMAL;
2397 e_multipoint_location = param->disconnectinfo.location;
2399 if (param->disconnectinfo.cause==CAUSE_BUSY && e_multipoint_cause!=CAUSE_REJECTED && e_multipoint_cause!=CAUSE_NORMAL) /* busy */
2401 e_multipoint_cause = CAUSE_BUSY;
2402 e_multipoint_location = param->disconnectinfo.location;
2404 if (param->disconnectinfo.cause==CAUSE_OUTOFORDER && e_multipoint_cause!=CAUSE_BUSY && e_multipoint_cause!=CAUSE_REJECTED && e_multipoint_cause!=CAUSE_NORMAL) /* no L1 */
2406 e_multipoint_cause = CAUSE_OUTOFORDER;
2407 e_multipoint_location = param->disconnectinfo.location;
2409 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 */
2411 e_multipoint_cause = param->disconnectinfo.cause;
2412 e_multipoint_location = param->disconnectinfo.location;
2414 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) new multipoint cause %d location %d.\n", ea_endpoint->ep_serial, e_multipoint_cause, e_multipoint_location);
2416 /* check if we have more than one portlist relation and we just ignore the disconnect */
2417 if (ea_endpoint->ep_portlist) if (ea_endpoint->ep_portlist->next)
2419 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) the disconnect was from a multipoint call. we just release that relation.\n", ea_endpoint->ep_serial);
2420 portlist = ea_endpoint->ep_portlist;
2423 if (portlist->port_id == port_id)
2425 portlist = portlist->next;
2429 PERROR("EPOINT(%d) software error: no portlist related to the calling port.\n", ea_endpoint->ep_serial);
2432 if (message_type != MESSAGE_RELEASE)
2434 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_RELEASE);
2435 message->param.disconnectinfo.cause = CAUSE_NORMAL; /* normal clearing */
2436 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2437 message_put(message);
2438 logmessage(message);
2440 ea_endpoint->free_portlist(portlist);
2441 return; /* one relation removed */
2443 if (e_multipoint_cause)
2445 cause = e_multipoint_cause;
2446 location = e_multipoint_location;
2449 cause = param->disconnectinfo.cause;
2450 location = param->disconnectinfo.location;
2453 e_cfnr_call = e_cfnr_release = 0;
2455 /* process hangup */
2456 process_hangup(e_call_cause, e_call_location);
2457 e_multipoint_cause = 0;
2458 e_multipoint_location = LOCATION_PRIVATE_LOCAL;
2460 /* tone to disconnected end */
2461 SPRINT(buffer, "cause_%02x", cause);
2462 if (ea_endpoint->ep_portlist)
2463 set_tone(ea_endpoint->ep_portlist, buffer);
2465 new_state(EPOINT_STATE_IN_DISCONNECT);
2466 if (ea_endpoint->ep_call_id)
2468 int haspatterns = 0;
2469 /* check if pattern is available */
2470 if (ea_endpoint->ep_portlist)
2471 if (!ea_endpoint->ep_portlist->next)
2472 if ((ea_endpoint->ep_portlist->port_type==PORT_TYPE_DSS1_TE_OUT) || (ea_endpoint->ep_portlist->port_type==PORT_TYPE_DSS1_TE_IN))
2473 #warning wie ist das bei einem asterisk, gibts auch tones?
2474 if (callpbx_countrelations(ea_endpoint->ep_call_id)==2 // we must count relations, in order not to disturb the conference ; NOTE:
2475 && message_type != MESSAGE_RELEASE) // if we release, we are done
2479 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) the port has patterns.\n", ea_endpoint->ep_serial);
2480 /* indicate patterns */
2481 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_PATTERN);
2482 message_put(message);
2483 /* connect audio, if not already */
2484 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
2485 message->param.channel = CHANNEL_STATE_CONNECT;
2486 message_put(message);
2487 /* send disconnect */
2488 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, message_type);
2489 memcpy(&message->param, param, sizeof(union parameter));
2490 message_put(message);
2491 /* disable encryption if disconnected */
2492 //PERROR("REMOVE ME: state =%d, %d\n", e_crypt_state, e_crypt);
2494 cryptman_message(CI_DISCONNECT_IND, NULL, 0);
2498 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) the port has no patterns.\n", ea_endpoint->ep_serial);
2501 release(RELEASE_ALL, location, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, callcause, portcause */
2502 return; /* must exit here */
2505 /* port MESSAGE_TIMEOUT */
2506 void EndpointAppPBX::port_timeout(struct port_list *portlist, int message_type, union parameter *param)
2510 printlog("%3d incoming TIMEOUT\n",
2511 ea_endpoint->ep_serial
2513 message_type = MESSAGE_DISCONNECT;
2514 switch (param->state)
2516 case PORT_STATE_OUT_SETUP:
2517 case PORT_STATE_OUT_OVERLAP:
2518 /* no user responding */
2519 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOUSER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
2520 return; /* must exit here */
2522 case PORT_STATE_IN_SETUP:
2523 case PORT_STATE_IN_OVERLAP:
2524 param->disconnectinfo.cause = CAUSE_INVALID; /* number incomplete */
2525 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2528 case PORT_STATE_OUT_PROCEEDING:
2529 param->disconnectinfo.cause = CAUSE_NOUSER; /* no user responding */
2530 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2531 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOUSER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
2532 return; /* must exit here */
2534 case PORT_STATE_IN_PROCEEDING:
2535 param->disconnectinfo.cause = CAUSE_NOUSER;
2536 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL; /* no user responding */
2539 case PORT_STATE_OUT_ALERTING:
2540 param->disconnectinfo.cause = CAUSE_NOANSWER; /* no answer */
2541 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2542 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOANSWER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
2543 return; /* must exit here */
2545 case PORT_STATE_IN_ALERTING:
2546 param->disconnectinfo.cause = CAUSE_NOANSWER;
2547 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2550 case PORT_STATE_IN_DISCONNECT:
2551 case PORT_STATE_OUT_DISCONNECT:
2552 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) in this special case, we release due to disconnect timeout.\n", ea_endpoint->ep_serial);
2553 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
2554 return; /* must exit here */
2557 param->disconnectinfo.cause = 31; /* normal unspecified */
2558 param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2560 /* release call, disconnect isdn */
2562 new_state(EPOINT_STATE_OUT_DISCONNECT);
2563 SPRINT(cause, "cause_%02x", param->disconnectinfo.cause);
2564 SCPY(e_tone, cause);
2567 set_tone(portlist, cause);
2568 message_disconnect_port(portlist, param->disconnectinfo.cause, param->disconnectinfo.location, "");
2569 portlist = portlist->next;
2571 release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
2574 /* port MESSAGE_NOTIFY */
2575 void EndpointAppPBX::port_notify(struct port_list *portlist, int message_type, union parameter *param)
2577 struct message *message;
2581 /* signal to call tool */
2582 admin_call_response(e_adminid, ADMIN_CALL_NOTIFY, numberrize_callerinfo(param->notifyinfo.id,param->notifyinfo.ntype), 0, 0, param->notifyinfo.notify);
2583 if (param->notifyinfo.notify)
2585 e_rx_state = track_notify(e_rx_state, param->notifyinfo.notify);
2588 /* if we get notification from stack, local shows if we disabled/enabled audio stream */
2589 if (param->notifyinfo.local) switch(param->notifyinfo.notify)
2591 case INFO_NOTIFY_REMOTE_HOLD:
2592 case INFO_NOTIFY_USER_SUSPENDED:
2593 /* tell call about it */
2594 if (ea_endpoint->ep_call_id)
2596 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
2597 message->param.channel = CHANNEL_STATE_HOLD;
2598 message_put(message);
2602 case INFO_NOTIFY_REMOTE_RETRIEVAL:
2603 case INFO_NOTIFY_USER_RESUMED:
2604 /* set volume of rx and tx */
2605 if (param->setup.callerinfo.itype == INFO_ITYPE_INTERN)
2606 if (e_ext.txvol!=256 || e_ext.rxvol!=256)
2609 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_mISDNSIGNAL);
2610 message->param.mISDNsignal.message = mISDNSIGNAL_VOLUME;
2611 message->param.mISDNsignal.rxvol = e_ext.txvol;
2612 message->param.mISDNsignal.txvol = e_ext.rxvol;
2613 message_put(message);
2615 /* set current tone */
2617 set_tone(portlist, e_tone);
2618 /* tell call about it */
2619 if (ea_endpoint->ep_call_id)
2621 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
2622 message->param.channel = CHANNEL_STATE_CONNECT;
2623 message_put(message);
2628 /* get name of notify */
2629 switch(param->notifyinfo.notify)
2635 logtext = "USER_SUSPENDED";
2638 logtext = "BEARER_SERVICE_CHANGED";
2641 logtext = "USER_RESUMED";
2644 logtext = "CONFERENCE_ESTABLISHED";
2647 logtext = "CONFERENCE_DISCONNECTED";
2650 logtext = "OTHER_PARTY_ADDED";
2653 logtext = "ISOLATED";
2656 logtext = "REATTACHED";
2659 logtext = "OTHER_PARTY_ISOLATED";
2662 logtext = "OTHER_PARTY_REATTACHED";
2665 logtext = "OTHER_PARTY_SPLIT";
2668 logtext = "OTHER_PARTY_DISCONNECTED";
2671 logtext = "CONFERENCE_FLOATING";
2674 logtext = "CONFERENCE_DISCONNECTED_PREEMTED";
2677 logtext = "CONFERENCE_FLOATING_SERVED_USER_PREEMTED";
2680 logtext = "CALL_IS_A_WAITING_CALL";
2683 logtext = "DIVERSION_ACTIVATED";
2686 logtext = "RESERVED_CT_1";
2689 logtext = "RESERVED_CT_2";
2692 logtext = "REVERSE_CHARGING";
2695 logtext = "REMOTE_HOLD";
2698 logtext = "REMOTE_RETRIEVAL";
2701 logtext = "CALL_IS_DIVERTING";
2704 SPRINT(buffer, "indicator=%d", param->notifyinfo.notify - 0x80);
2708 printlog("%3d incoming NOTIFY notify='%s' id='%s'%s\n",
2709 ea_endpoint->ep_serial,
2711 param->notifyinfo.id,
2712 (param->notifyinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":""
2715 /* notify call if available */
2716 if (ea_endpoint->ep_call_id)
2718 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_NOTIFY);
2719 memcpy(&message->param.notifyinfo, ¶m->notifyinfo, sizeof(struct notify_info));
2720 message_put(message);
2725 /* port MESSAGE_FACILITY */
2726 void EndpointAppPBX::port_facility(struct port_list *portlist, int message_type, union parameter *param)
2728 struct message *message;
2730 printlog("%3d incoming FACILITY len='%d'\n",
2731 ea_endpoint->ep_serial,
2732 param->facilityinfo.len
2735 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_FACILITY);
2736 memcpy(&message->param.facilityinfo, ¶m->facilityinfo, sizeof(struct facility_info));
2737 message_put(message);
2740 /* port MESSAGE_SUSPEND */
2741 /* NOTE: before supending, the inactive-notification must be done in order to set call mixer */
2742 void EndpointAppPBX::port_suspend(struct port_list *portlist, int message_type, union parameter *param)
2744 printlog("%3d incoming SUSPEND\n",
2745 ea_endpoint->ep_serial
2747 /* epoint is now parked */
2748 ea_endpoint->ep_park = 1;
2749 memcpy(ea_endpoint->ep_park_callid, param->parkinfo.callid, sizeof(ea_endpoint->ep_park_callid));
2750 ea_endpoint->ep_park_len = (param->parkinfo.len>8)?8:param->parkinfo.len;
2752 /* remove port relation */
2753 ea_endpoint->free_portlist(portlist);
2756 /* port MESSAGE_RESUME */
2757 /* NOTE: before resume, the active-notification must be done in order to set call mixer */
2758 void EndpointAppPBX::port_resume(struct port_list *portlist, int message_type, union parameter *param)
2760 printlog("%3d incoming RESUME\n",
2761 ea_endpoint->ep_serial
2763 /* epoint is now resumed */
2764 ea_endpoint->ep_park = 0;
2769 /* port sends message to the endpoint
2771 void EndpointAppPBX::ea_message_port(unsigned long port_id, int message_type, union parameter *param)
2773 struct port_list *portlist;
2774 struct message *message;
2777 portlist = ea_endpoint->ep_portlist;
2780 if (port_id == portlist->port_id)
2782 portlist = portlist->next;
2786 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);
2790 // PDEBUG(DEBUG_EPOINT, "received message %d (terminal %s, caller id %s)\n", message, e_terminal, e_callerinfo.id);
2791 switch(message_type)
2793 case MESSAGE_DATA: /* data from port */
2794 /* send back to source for recording */
2797 message = message_create(ea_endpoint->ep_serial, port_id, EPOINT_TO_PORT, message_type);
2798 memcpy(&message->param, param, sizeof(union parameter));
2799 message_put(message);
2802 /* check if there is a call */
2803 if (!ea_endpoint->ep_call_id)
2805 /* continue if only one portlist */
2806 if (ea_endpoint->ep_portlist->next != NULL)
2808 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, message_type);
2809 memcpy(&message->param, param, sizeof(union parameter));
2810 message_put(message);
2813 case MESSAGE_TONE_EOF: /* tone is end of file */
2814 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) current tone is now end of file.\n", ea_endpoint->ep_serial);
2817 if (e_action->index == ACTION_VBOX_PLAY)
2821 if (e_action->index == ACTION_EFI)
2828 case MESSAGE_TONE_COUNTER: /* counter info received */
2829 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);
2831 if (e_action->index == ACTION_VBOX_PLAY)
2833 e_vbox_counter = param->counter.current;
2834 if (param->counter.max >= 0)
2835 e_vbox_counter_max = param->counter.max;
2839 /* PORT sends SETUP message */
2841 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);
2842 if (e_state!=EPOINT_STATE_IDLE)
2844 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in idle state.\n", ea_endpoint->ep_serial);
2847 port_setup(portlist, message_type, param);
2850 /* PORT sends INFORMATION message */
2851 case MESSAGE_INFORMATION: /* additional digits received */
2852 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);
2853 port_information(portlist, message_type, param);
2856 /* PORT sends FACILITY message */
2857 case MESSAGE_FACILITY:
2858 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming facility (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
2859 port_facility(portlist, message_type, param);
2862 /* PORT sends DTMF message */
2863 case MESSAGE_DTMF: /* dtmf digits received */
2864 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);
2865 port_dtmf(portlist, message_type, param);
2868 /* PORT sends CRYPT message */
2869 case MESSAGE_CRYPT: /* crypt response received */
2870 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) crypt response=%d\n", ea_endpoint->ep_serial, param->crypt.type);
2871 port_crypt(portlist, message_type, param);
2874 /* PORT sends MORE message */
2875 case MESSAGE_OVERLAP:
2876 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);
2877 if (e_state != EPOINT_STATE_OUT_SETUP)
2879 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);
2882 port_overlap(portlist, message_type, param);
2885 /* PORT sends PROCEEDING message */
2886 case MESSAGE_PROCEEDING: /* port is proceeding */
2887 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) outgoing call is proceeding (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
2888 if (e_state!=EPOINT_STATE_OUT_SETUP
2889 && e_state!=EPOINT_STATE_OUT_OVERLAP)
2891 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);
2894 port_proceeding(portlist, message_type, param);
2897 /* PORT sends ALERTING message */
2898 case MESSAGE_ALERTING:
2899 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) outgoing call is ringing (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
2900 if (e_state!=EPOINT_STATE_OUT_SETUP
2901 && e_state!=EPOINT_STATE_OUT_OVERLAP
2902 && e_state!=EPOINT_STATE_OUT_PROCEEDING)
2904 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);
2907 port_alerting(portlist, message_type, param);
2910 /* PORT sends CONNECT message */
2911 case MESSAGE_CONNECT:
2912 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);
2913 if (e_state!=EPOINT_STATE_OUT_SETUP
2914 && e_state!=EPOINT_STATE_OUT_OVERLAP
2915 && e_state!=EPOINT_STATE_OUT_PROCEEDING
2916 && e_state!=EPOINT_STATE_OUT_ALERTING)
2918 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in setup, proceeding or alerting state.\n", ea_endpoint->ep_serial);
2921 port_connect(portlist, message_type, param);
2924 /* PORT sends DISCONNECT message */
2925 case MESSAGE_DISCONNECT: /* port is disconnected */
2926 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);
2927 port_disconnect_release(portlist, message_type, param);
2930 /* PORT sends a RELEASE message */
2931 case MESSAGE_RELEASE: /* port releases */
2932 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);
2933 /* portlist is release at port_disconnect_release, thanx Paul */
2934 port_disconnect_release(portlist, message_type, param);
2937 /* PORT sends a TIMEOUT message */
2938 case MESSAGE_TIMEOUT:
2939 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);
2940 port_timeout(portlist, message_type, param);
2941 break; /* release */
2943 /* PORT sends a NOTIFY message */
2944 case MESSAGE_NOTIFY:
2945 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received notify.\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
2946 port_notify(portlist, message_type, param);
2949 /* PORT sends a SUSPEND message */
2950 case MESSAGE_SUSPEND:
2951 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received suspend.\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
2952 port_suspend(portlist, message_type, param);
2953 break; /* suspend */
2955 /* PORT sends a RESUME message */
2956 case MESSAGE_RESUME:
2957 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received resume.\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
2958 port_resume(portlist, message_type, param);
2961 case MESSAGE_VBOX_RECORD:
2962 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);
2963 /* check if we are a terminal */
2964 if (e_terminal[0] == '\0')
2965 PERROR("Port(%d) cannot record because we are not a terminal\n", ea_endpoint->ep_serial);
2968 port = find_port_id(portlist->port_id);
2970 port->open_record(e_ext.vbox_codec, 2, 0, e_terminal, e_ext.anon_ignore, e_ext.vbox_email, e_ext.vbox_email_file);
2972 /* the recording is done to the vbox directory rather than to the recording directory (using vbox_codec) */
2976 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);
2979 /* Note: this endpoint may be destroyed, so we MUST return */
2983 /* messages from port
2985 /* call MESSAGE_CRYPT */
2986 void EndpointAppPBX::call_crypt(struct port_list *portlist, int message_type, union parameter *param)
2988 switch(param->crypt.type)
2990 /* message from remote port to "crypt manager" */
2991 case CU_ACTK_REQ: /* activate key-exchange */
2992 case CU_ACTS_REQ: /* activate shared key */
2993 case CU_DACT_REQ: /* deactivate */
2994 case CU_INFO_REQ: /* request last info message */
2995 cryptman_message(param->crypt.type, param->crypt.data, param->crypt.len);
2998 /* message from "crypt manager" to user */
2999 case CU_ACTK_CONF: /* key-echange done */
3000 case CU_ACTS_CONF: /* shared key done */
3001 case CU_DACT_CONF: /* deactivated */
3002 case CU_DACT_IND: /* deactivated */
3003 case CU_ERROR_IND: /* receive error message */
3004 case CU_INFO_IND: /* receive info message */
3005 case CU_INFO_CONF: /* receive info message */
3006 encrypt_result(param->crypt.type, (char *)param->crypt.data);
3010 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);
3014 /* call MESSAGE_INFORMATION */
3015 void EndpointAppPBX::call_information(struct port_list *portlist, int message_type, union parameter *param)
3017 struct message *message;
3023 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_INFORMATION);
3024 memcpy(&message->param.information, ¶m->information, sizeof(struct dialing_info));
3025 message_put(message);
3026 logmessage(message);
3027 portlist = portlist->next;
3031 /* call MESSAGE_FACILITY */
3032 void EndpointAppPBX::call_facility(struct port_list *portlist, int message_type, union parameter *param)
3034 struct message *message;
3036 if (!e_ext.facility)
3043 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_FACILITY);
3044 memcpy(&message->param.facilityinfo, ¶m->facilityinfo, sizeof(struct facility_info));
3045 message_put(message);
3046 logmessage(message);
3047 portlist = portlist->next;
3051 /* call MESSAGE_MORE */
3052 void EndpointAppPBX::call_overlap(struct port_list *portlist, int message_type, union parameter *param)
3054 struct message *message;
3056 new_state(EPOINT_STATE_IN_OVERLAP);
3059 if (e_call_pattern && e_ext.own_setup)
3061 /* disconnect audio */
3062 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
3063 message->param.channel = CHANNEL_STATE_HOLD;
3064 message_put(message);
3066 if (e_action) if (e_action->index == ACTION_OUTDIAL || e_action->index == ACTION_EXTERNAL)
3068 set_tone(portlist, "dialtone");
3072 set_tone(portlist, "dialpbx");
3074 set_tone(portlist, "dialtone");
3077 /* call MESSAGE_PROCEEDING */
3078 void EndpointAppPBX::call_proceeding(struct port_list *portlist, int message_type, union parameter *param)
3080 struct message *message;
3082 new_state(EPOINT_STATE_IN_PROCEEDING);
3084 /* own proceeding tone */
3087 /* connect / disconnect audio */
3088 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
3089 if (e_ext.own_proceeding)
3090 message->param.channel = CHANNEL_STATE_HOLD;
3092 message->param.channel = CHANNEL_STATE_CONNECT;
3093 message_put(message);
3095 // UCPY(e_call_tone, "proceeding");
3098 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
3099 message_put(message);
3100 logmessage(message);
3102 set_tone(portlist, "proceeding");
3105 /* call MESSAGE_ALERTING */
3106 void EndpointAppPBX::call_alerting(struct port_list *portlist, int message_type, union parameter *param)
3108 struct message *message;
3110 new_state(EPOINT_STATE_IN_ALERTING);
3112 /* own alerting tone */
3115 /* connect / disconnect audio */
3116 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
3117 if (e_ext.own_alerting)
3118 message->param.channel = CHANNEL_STATE_HOLD;
3120 message->param.channel = CHANNEL_STATE_CONNECT;
3121 message_put(message);
3125 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_ALERTING);
3126 message_put(message);
3127 logmessage(message);
3129 if (e_action) if (e_action->index == ACTION_OUTDIAL || e_action->index == ACTION_EXTERNAL)
3131 set_tone(portlist, "ringing");
3135 set_tone(portlist, "ringpbx");
3137 set_tone(portlist, "ringing");
3140 /* call MESSAGE_CONNECT */
3141 void EndpointAppPBX::call_connect(struct port_list *portlist, int message_type, union parameter *param)
3143 struct message *message;
3145 new_state(EPOINT_STATE_CONNECT);
3146 // UCPY(e_call_tone, "");
3148 e_dtmf = 1; /* allow dtmf */
3150 memcpy(&e_connectinfo, ¶m->connectinfo, sizeof(e_callerinfo));
3153 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
3154 memcpy(&message->param, param, sizeof(union parameter));
3155 /* screen clip if prefix is required */
3156 if (e_terminal[0] && message->param.connectinfo.id[0] && e_ext.clip_prefix[0])
3158 SCPY(message->param.connectinfo.id, e_ext.clip_prefix);
3159 SCAT(message->param.connectinfo.id, numberrize_callerinfo(e_connectinfo.id,e_connectinfo.ntype));
3160 message->param.connectinfo.ntype = INFO_NTYPE_UNKNOWN;
3162 /* use internal caller id */
3163 if (e_terminal[0] && e_connectinfo.intern[0] && (message->param.connectinfo.present!=INFO_PRESENT_RESTRICTED || e_ext.anon_ignore))
3165 SCPY(message->param.connectinfo.id, e_connectinfo.intern);
3166 message->param.connectinfo.ntype = INFO_NTYPE_UNKNOWN;
3168 /* handle restricted caller ids */
3169 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);
3170 /* display callerid if desired for extension */
3171 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));
3172 /* use conp, if enabld */
3174 message->param.connectinfo.name[0] = '\0';
3176 message_put(message);
3177 logmessage(message);
3179 set_tone(portlist, NULL);
3181 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
3182 message->param.channel = CHANNEL_STATE_CONNECT;
3183 message_put(message);
3187 /* call MESSAGE_DISCONNECT MESSAGE_RELEASE */
3188 void EndpointAppPBX::call_disconnect_release(struct port_list *portlist, int message_type, union parameter *param)
3191 struct message *message;
3194 /* be sure that we are active */
3196 e_tx_state = NOTIFY_STATE_ACTIVE;
3198 /* we are powerdialing, if e_powerdialing is set and limit is not exceeded if given */
3199 if (e_powerdialing && ((e_powercount+1)<e_powerlimit || e_powerlimit<1))
3201 release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
3203 /* set time for power dialing */
3204 e_powerdialing = now_d + e_powerdelay; /* set redial in the future */
3207 /* set redial tone */
3208 if (ea_endpoint->ep_portlist)
3212 set_tone(ea_endpoint->ep_portlist, "redial");
3213 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);
3214 /* send proceeding when powerdialing and still setup (avoid dialing timeout) */
3215 if (e_state==EPOINT_STATE_IN_OVERLAP)
3217 new_state(EPOINT_STATE_IN_PROCEEDING);
3220 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
3221 message_put(message);
3222 logmessage(message);
3224 /* caused the error, that the first knock sound was not there */
3225 /* set_tone(portlist, "proceeding"); */
3227 /* send display of powerdialing */
3228 if (e_ext.display_dialing)
3232 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
3234 SPRINT(message->param.notifyinfo.display, "Retry %d of %d", e_powercount, e_powerlimit);
3236 SPRINT(message->param.notifyinfo.display, "Retry %d", e_powercount);
3237 message_put(message);
3238 logmessage(message);
3239 portlist = portlist->next;
3248 if ((e_state!=EPOINT_STATE_CONNECT
3249 && e_state!=EPOINT_STATE_OUT_DISCONNECT
3250 && e_state!=EPOINT_STATE_IN_OVERLAP
3251 && e_state!=EPOINT_STATE_IN_PROCEEDING
3252 && e_state!=EPOINT_STATE_IN_ALERTING)
3253 || !ea_endpoint->ep_portlist) /* or no port */
3255 process_hangup(param->disconnectinfo.cause, param->disconnectinfo.location);
3256 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, param->disconnectinfo.cause); /* RELEASE_TYPE, call, port */
3257 return; /* must exit here */
3262 e_call_cause = param->disconnectinfo.cause;
3263 e_call_location = param->disconnectinfo.location;
3266 /* on release we need the audio again! */
3267 if (message_type == MESSAGE_RELEASE)
3270 ea_endpoint->ep_call_id = 0;
3272 /* disconnect and select tone */
3273 new_state(EPOINT_STATE_OUT_DISCONNECT);
3274 SPRINT(cause, "cause_%02x", param->disconnectinfo.cause);
3275 /* if own_cause, we must release the call */
3276 if (e_ext.own_cause /* own cause */
3277 || !e_call_pattern) /* no patterns */
3279 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);
3280 if (message_type != MESSAGE_RELEASE)
3281 release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
3283 } else /* else we enable audio */
3285 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
3286 message->param.channel = CHANNEL_STATE_CONNECT;
3287 message_put(message);
3289 /* send disconnect message */
3290 SCPY(e_tone, cause);
3293 set_tone(portlist, cause);
3294 message_disconnect_port(portlist, param->disconnectinfo.cause, param->disconnectinfo.location, "");
3295 portlist = portlist->next;
3299 /* call MESSAGE_SETUP */
3300 void EndpointAppPBX::call_setup(struct port_list *portlist, int message_type, union parameter *param)
3302 struct message *message;
3304 /* if we already in setup state, we just update the dialing with new digits */
3305 if (e_state == EPOINT_STATE_OUT_SETUP
3306 || e_state == EPOINT_STATE_OUT_OVERLAP)
3308 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) we are in setup state, so we do overlap dialing.\n", ea_endpoint->ep_serial);
3309 /* if digits changed, what we have already dialed */
3310 if (!!strncmp(e_dialinginfo.number,param->setup.dialinginfo.number,strlen(e_dialinginfo.number)))
3312 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);
3313 /* release all ports */
3314 while((portlist = ea_endpoint->ep_portlist))
3316 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_RELEASE);
3317 message->param.disconnectinfo.cause = CAUSE_NORMAL; /* normal clearing */
3318 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
3319 message_put(message);
3320 logmessage(message);
3321 ea_endpoint->free_portlist(portlist);
3324 /* disconnect audio */
3325 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
3326 message->param.channel = CHANNEL_STATE_HOLD;
3327 message_put(message);
3329 /* get dialing info */
3330 memcpy(&e_callerinfo, ¶m->setup.callerinfo, sizeof(e_callerinfo));
3331 memcpy(&e_dialinginfo, ¶m->setup.dialinginfo, sizeof(e_dialinginfo));
3332 memcpy(&e_redirinfo, ¶m->setup.redirinfo, sizeof(e_redirinfo));
3333 memcpy(&e_capainfo, ¶m->setup.capainfo, sizeof(e_capainfo));
3334 new_state(EPOINT_STATE_OUT_OVERLAP);
3337 e_redial = now_d + 1; /* set redial one second in the future */
3340 /* if we have a pending redial, so we just adjust the dialing number */
3343 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);
3344 memcpy(&e_dialinginfo, ¶m->setup.dialinginfo, sizeof(e_dialinginfo));
3347 if (!ea_endpoint->ep_portlist)
3349 PERROR("ERROR: overlap dialing to a NULL port relation\n");
3351 if (ea_endpoint->ep_portlist->next)
3353 PERROR("ERROR: overlap dialing to a port_list port relation\n");
3355 if (e_state == EPOINT_STATE_OUT_SETUP)
3358 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);
3359 SCAT(e_dialing_queue, param->setup.dialinginfo.number + strlen(e_dialinginfo.number));
3363 /* get what we have not dialed yet */
3364 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));
3365 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_INFORMATION);
3366 SCPY(message->param.information.number, param->setup.dialinginfo.number + strlen(e_dialinginfo.number));
3367 message->param.information.ntype = INFO_NTYPE_UNKNOWN;
3368 message_put(message);
3369 logmessage(message);
3371 /* always store what we have dialed or queued */
3372 memcpy(&e_dialinginfo, ¶m->setup.dialinginfo, sizeof(e_dialinginfo));
3376 if (e_state != EPOINT_STATE_IDLE)
3378 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in idle state.\n", ea_endpoint->ep_serial);
3381 /* if an internal extension is dialed, copy that number */
3382 if (param->setup.dialinginfo.itype==INFO_ITYPE_INTERN || param->setup.dialinginfo.itype==INFO_ITYPE_VBOX)
3383 SCPY(e_terminal, param->setup.dialinginfo.number);
3384 /* if an internal extension is dialed, get extension's info about caller */
3387 if (!read_extension(&e_ext, e_terminal))
3389 e_terminal[0] = '\0';
3390 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) the called terminal='%s' is not found in directory tree!\n", ea_endpoint->ep_serial, e_terminal);
3394 memcpy(&e_callerinfo, ¶m->setup.callerinfo, sizeof(e_callerinfo));
3395 memcpy(&e_dialinginfo, ¶m->setup.dialinginfo, sizeof(e_dialinginfo));
3396 memcpy(&e_redirinfo, ¶m->setup.redirinfo, sizeof(e_redirinfo));
3397 memcpy(&e_capainfo, ¶m->setup.capainfo, sizeof(e_capainfo));
3399 /* process (voice over) data calls */
3400 if (e_ext.datacall && e_capainfo.bearer_capa!=INFO_BC_SPEECH && e_capainfo.bearer_capa!=INFO_BC_AUDIO)
3402 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) handling data call as audio call: '%s'\n", ea_endpoint->ep_serial, e_terminal);
3403 memset(&e_capainfo, 0, sizeof(e_capainfo));
3404 e_capainfo.bearer_capa = INFO_BC_AUDIO;
3405 e_capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
3406 e_capainfo.bearer_info1 = (options.law=='u')?INFO_INFO1_ULAW:INFO_INFO1_ALAW;
3409 new_state(EPOINT_STATE_OUT_SETUP);
3410 /* call special setup routine */
3414 /* call MESSAGE_mISDNSIGNAL */
3415 void EndpointAppPBX::call_mISDNsignal(struct port_list *portlist, int message_type, union parameter *param)
3417 struct message *message;
3421 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_mISDNSIGNAL);
3422 memcpy(&message->param, param, sizeof(union parameter));
3423 message_put(message);
3424 portlist = portlist->next;
3428 /* call MESSAGE_NOTIFY */
3429 void EndpointAppPBX::call_notify(struct port_list *portlist, int message_type, union parameter *param)
3431 struct message *message;
3434 if (param->notifyinfo.notify)
3436 new_state = track_notify(e_tx_state, param->notifyinfo.notify);
3437 // /* if notification was generated locally, we turn hold music on/off */
3438 // if (param->notifyinfo.local)
3439 // 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)
3444 if (new_state!=NOTIFY_STATE_HOLD && new_state!=NOTIFY_STATE_SUSPEND)
3448 set_tone(portlist, "");
3449 portlist = portlist->next;
3451 portlist = ea_endpoint->ep_portlist;
3456 if (new_state==NOTIFY_STATE_HOLD || new_state==NOTIFY_STATE_SUSPEND)
3460 set_tone(portlist, "hold");
3461 portlist = portlist->next;
3463 portlist = ea_endpoint->ep_portlist;
3468 /* save new state */
3469 e_tx_state = new_state;
3472 /* notify port(s) about it */
3475 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
3476 memcpy(&message->param.notifyinfo, ¶m->notifyinfo, sizeof(struct notify_info));
3477 /* handle restricted caller ids */
3478 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);
3479 /* display callerid if desired for extension */
3480 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));
3481 message_put(message);
3482 logmessage(message);
3483 portlist = portlist->next;
3487 /* call sends messages to the endpoint
3489 void EndpointAppPBX::ea_message_call(unsigned long call_id, int message_type, union parameter *param)
3491 struct port_list *portlist;
3492 struct message *message;
3496 PERROR("EPOINT(%d) error: call == NULL.\n", ea_endpoint->ep_serial);
3500 portlist = ea_endpoint->ep_portlist;
3502 /* send MESSAGE_DATA to port */
3503 if (call_id == ea_endpoint->ep_call_id)
3505 if (message_type == MESSAGE_DATA)
3507 /* skip if no port relation */
3510 /* skip if more than one port relation */
3513 /* send audio data to port */
3514 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_DATA);
3515 memcpy(&message->param, param, sizeof(union parameter));
3516 message_put(message);
3521 // 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);
3522 switch(message_type)
3524 /* CALL SENDS CRYPT message */
3526 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);
3527 call_crypt(portlist, message_type, param);
3530 /* CALL sends INFORMATION message */
3531 case MESSAGE_INFORMATION:
3532 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);
3533 call_information(portlist, message_type, param);
3536 /* CALL sends FACILITY message */
3537 case MESSAGE_FACILITY:
3538 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received facility\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3539 call_facility(portlist, message_type, param);
3542 /* CALL sends OVERLAP message */
3543 case MESSAGE_OVERLAP:
3544 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);
3545 if (e_state!=EPOINT_STATE_IN_SETUP
3546 && e_state!=EPOINT_STATE_IN_OVERLAP)
3548 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in setup state.\n", ea_endpoint->ep_serial);
3551 call_overlap(portlist, message_type, param);
3554 /* CALL sends PROCEEDING message */
3555 case MESSAGE_PROCEEDING:
3556 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s (caller id '%s') received proceeding\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3557 if(e_state!=EPOINT_STATE_IN_OVERLAP)
3559 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in setup state.\n", ea_endpoint->ep_serial);
3562 call_proceeding(portlist, message_type, param);
3565 /* CALL sends ALERTING message */
3566 case MESSAGE_ALERTING:
3567 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received alerting\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3568 if (e_state!=EPOINT_STATE_IN_OVERLAP
3569 && e_state!=EPOINT_STATE_IN_PROCEEDING)
3571 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in setup or proceeding state.\n", ea_endpoint->ep_serial);
3574 call_alerting(portlist, message_type, param);
3577 /* CALL sends CONNECT message */
3578 case MESSAGE_CONNECT:
3579 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received connect\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3580 if (e_state!=EPOINT_STATE_IN_OVERLAP
3581 && e_state!=EPOINT_STATE_IN_PROCEEDING
3582 && e_state!=EPOINT_STATE_IN_ALERTING)
3584 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ignored because we are not in setup, proceeding or alerting state.\n", ea_endpoint->ep_serial);
3587 call_connect(portlist, message_type, param);
3590 /* CALL sends DISCONNECT/RELEASE message */
3591 case MESSAGE_DISCONNECT: /* call disconnect */
3592 case MESSAGE_RELEASE: /* call releases */
3593 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);
3594 call_disconnect_release(portlist, message_type, param);
3597 /* CALL sends SETUP message */
3599 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);
3600 call_setup(portlist, message_type, param);
3604 /* CALL sends special mISDNSIGNAL message */
3605 case MESSAGE_mISDNSIGNAL: /* isdn message to port */
3606 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);
3607 call_mISDNsignal(portlist, message_type, param);
3610 /* CALL has pattern available */
3611 case MESSAGE_PATTERN: /* indicating pattern available */
3612 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);
3613 if (!e_call_pattern)
3615 PDEBUG(DEBUG_EPOINT, "-> pattern becomes available\n");
3620 set_tone(portlist, NULL);
3621 portlist = portlist->next;
3623 /* connect our audio tx and rx (blueboxing should be possibe before connect :)*/
3624 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
3625 message->param.channel = CHANNEL_STATE_CONNECT;
3626 message_put(message);
3627 /* tell remote epoint to connect audio also, because we like to hear the patterns */
3628 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_REMOTE_AUDIO);
3629 message->param.channel = CHANNEL_STATE_CONNECT;
3630 message_put(message);
3634 /* CALL has no pattern available */
3635 case MESSAGE_NOPATTERN: /* indicating no pattern available */
3636 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);
3639 PDEBUG(DEBUG_EPOINT, "-> pattern becomes unavailable\n");
3641 /* disconnect our audio tx and rx */
3642 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
3643 message->param.channel = CHANNEL_STATE_HOLD;
3644 message_put(message);
3648 /* CALL (dunno at the moment) */
3649 case MESSAGE_REMOTE_AUDIO:
3650 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);
3651 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
3652 message->param.channel = param->channel;
3653 message_put(message);
3656 /* CALL sends a notify message */
3657 case MESSAGE_NOTIFY:
3658 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received notify.\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
3659 call_notify(portlist, message_type, param);
3663 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);
3668 /* pick_call will connect the first incoming call found. the endpoint
3669 * will receivce a MESSAGE_CONNECT.
3671 int match_list(char *list, char *item)
3673 char *end, *next = NULL;
3675 /* no list make matching */
3681 /* eliminate white spaces */
3682 while (*list <= ' ')
3689 /* if end of list is reached, we return */
3690 if (list[0] == '\0')
3692 /* if we have more than one entry (left) */
3693 if ((end = strchr(list, ',')))
3696 next = end = strchr(list, '\0');
3697 while (*(end-1) <= ' ')
3699 /* if string part matches item */
3700 if (!strncmp(list, item, end-list))
3706 void EndpointAppPBX::pick_call(char *extensions)
3708 struct message *message;
3709 struct port_list *portlist;
3711 class EndpointAppPBX *eapp, *found;
3713 class CallPBX *callpbx;
3714 struct call_relation *relation;
3717 /* find an endpoint that is ringing internally or vbox with higher priority */
3720 eapp = apppbx_first;
3723 if (eapp!=this && ea_endpoint->ep_portlist)
3725 portlist = eapp->ea_endpoint->ep_portlist;
3728 if ((port = find_port_id(portlist->port_id)))
3730 if (port->p_type == PORT_TYPE_VBOX_OUT)
3732 if (match_list(extensions, eapp->e_terminal))
3739 if ((port->p_type==PORT_TYPE_DSS1_NT_OUT || port->p_type==PORT_TYPE_DSS1_TE_OUT)
3740 && port->p_state==PORT_STATE_OUT_ALERTING)
3741 if (match_list(extensions, eapp->e_terminal))
3746 portlist = portlist->next;
3754 /* if no endpoint found */
3757 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);
3759 set_tone(ea_endpoint->ep_portlist, "cause_10");
3760 message_disconnect_port(ea_endpoint->ep_portlist, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, "");
3761 new_state(EPOINT_STATE_OUT_DISCONNECT);
3766 if (ea_endpoint->ep_call_id)
3768 PERROR("EPOINT(%d) we already have a call. SOFTWARE ERROR.\n", ea_endpoint->ep_serial);
3771 if (!eapp->ea_endpoint->ep_call_id)
3773 PERROR("EPOINT(%d) ringing endpoint has no call.\n", ea_endpoint->ep_serial);
3776 call = find_call_id(eapp->ea_endpoint->ep_call_id);
3779 PERROR("EPOINT(%d) ringing endpoint's call not found.\n", ea_endpoint->ep_serial);
3782 if (callpbx->c_type != CALL_TYPE_PBX)
3784 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ringing endpoint's call is not a PBX call, so we must reject.\n", ea_endpoint->ep_serial);
3787 callpbx = (class CallPBX *)call;
3788 relation = callpbx->c_relation;
3791 PERROR("EPOINT(%d) ringing endpoint's call has no relation. SOFTWARE ERROR.\n", ea_endpoint->ep_serial);
3794 while (relation->epoint_id != eapp->ea_endpoint->ep_serial)
3796 relation = relation->next;
3799 PERROR("EPOINT(%d) ringing endpoint's call has no relation to that call. SOFTWARE ERROR.\n", ea_endpoint->ep_serial);
3804 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) found ringing endpoint: %d.\n", ea_endpoint->ep_serial, eapp->ea_endpoint->ep_serial);
3806 if (options.deb & DEBUG_EPOINT)
3808 class Call *debug_c = call_first;
3809 class Endpoint *debug_e = epoint_first;
3810 class Port *debug_p = port_first;
3812 callpbx_debug(callpbx, "EndpointAppPBX::pick_call(before)");
3814 PDEBUG(DEBUG_EPOINT, "showing all calls:\n");
3817 PDEBUG(DEBUG_EPOINT, "call=%ld\n", debug_c->c_serial);
3818 debug_c = debug_c->next;
3820 PDEBUG(DEBUG_EPOINT, "showing all endpoints:\n");
3823 PDEBUG(DEBUG_EPOINT, "ep=%ld, call=%ld\n", debug_e->ep_serial, debug_e->ep_call_id);
3824 debug_e = debug_e->next;
3826 PDEBUG(DEBUG_EPOINT, "showing all ports:\n");
3829 PDEBUG(DEBUG_EPOINT, "port=%ld, ep=%ld (active)\n", debug_p->p_serial, ACTIVE_EPOINT(debug_p->p_epointlist));
3830 debug_p = debug_p->next;
3835 ea_endpoint->ep_call_id = eapp->ea_endpoint->ep_call_id; /* we get the call */
3836 relation->epoint_id = ea_endpoint->ep_serial; /* the call gets us */
3837 eapp->ea_endpoint->ep_call_id = 0; /* the ringing endpoint will get disconnected */
3839 /* connnecting our endpoint */
3840 new_state(EPOINT_STATE_CONNECT);
3842 set_tone(ea_endpoint->ep_portlist, NULL);
3844 /* now we send a release to the ringing endpoint */
3845 message = message_create(ea_endpoint->ep_call_id, eapp->ea_endpoint->ep_serial, CALL_TO_EPOINT, MESSAGE_RELEASE);
3846 message->param.disconnectinfo.cause = 26; /* non selected user clearing */
3847 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
3848 message_put(message);
3850 /* we send a connect to the call with our caller id */
3851 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CONNECT);
3852 SCPY(message->param.connectinfo.id, e_callerinfo.id);
3853 message->param.connectinfo.present = e_callerinfo.present;
3854 message->param.connectinfo.screen = e_callerinfo.screen;
3855 message->param.connectinfo.itype = e_callerinfo.itype;
3856 message->param.connectinfo.ntype = e_callerinfo.ntype;
3857 message_put(message);
3859 /* we send a connect to our port with the remote callerid */
3860 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
3861 SCPY(message->param.connectinfo.id, eapp->e_callerinfo.id);
3862 message->param.connectinfo.present = eapp->e_callerinfo.present;
3863 message->param.connectinfo.screen = eapp->e_callerinfo.screen;
3864 message->param.connectinfo.itype = eapp->e_callerinfo.itype;
3865 message->param.connectinfo.ntype = eapp->e_callerinfo.ntype;
3866 /* handle restricted caller ids */
3867 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);
3868 /* display callerid if desired for extension */
3869 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));
3870 message_put(message);
3872 /* we send a connect to the audio path (not for vbox) */
3873 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CHANNEL);
3874 message->param.channel = CHANNEL_STATE_CONNECT;
3875 message_put(message);
3877 /* beeing paranoid, we make call update */
3878 callpbx->c_mixer = 1;
3880 if (options.deb & DEBUG_EPOINT)
3882 class Call *debug_c = call_first;
3883 class Endpoint *debug_e = epoint_first;
3884 class Port *debug_p = port_first;
3886 callpbx_debug(callpbx, "EndpointAppPBX::pick_call(after)");
3888 PDEBUG(DEBUG_EPOINT, "showing all calls:\n");
3891 PDEBUG(DEBUG_EPOINT, "call=%ld\n", debug_c->c_serial);
3892 debug_c = debug_c->next;
3894 PDEBUG(DEBUG_EPOINT, "showing all endpoints:\n");
3897 PDEBUG(DEBUG_EPOINT, "ep=%ld, call=%ld\n", debug_e->ep_serial, debug_e->ep_call_id);
3898 debug_e = debug_e->next;
3900 PDEBUG(DEBUG_EPOINT, "showing all ports:\n");
3903 PDEBUG(DEBUG_EPOINT, "port=%ld, ep=%ld\n", debug_p->p_serial, ACTIVE_EPOINT(debug_p->p_epointlist));
3904 debug_p = debug_p->next;
3910 /* join calls (look for a call that is on hold (same isdn interface/terminal))
3912 void EndpointAppPBX::join_call(void)
3914 struct message *message;
3915 struct call_relation *our_relation, *other_relation;
3916 struct call_relation **our_relation_pointer, **other_relation_pointer;
3917 class Call *our_call, *other_call;
3918 class CallPBX *our_callpbx, *other_callpbx;
3919 class EndpointAppPBX *other_eapp; class Endpoint *temp_epoint;
3920 class Port *our_port, *other_port;
3921 class Pdss1 *our_pdss1, *other_pdss1;
3923 /* are we a candidate to join a call */
3924 our_call = find_call_id(ea_endpoint->ep_call_id);
3927 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: our call doesn't exist anymore.\n", ea_endpoint->ep_serial);
3930 if (our_call->c_type != CALL_TYPE_PBX)
3932 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: call is not a pbx call.\n", ea_endpoint->ep_serial);
3935 our_callpbx = (class CallPBX *)our_call;
3936 if (!ea_endpoint->ep_portlist)
3938 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: we have no port.\n", ea_endpoint->ep_serial);
3943 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: we are not internal extension.\n", ea_endpoint->ep_serial);
3946 our_port = find_port_id(ea_endpoint->ep_portlist->port_id);
3949 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: our port doesn't exist anymore.\n", ea_endpoint->ep_serial);
3952 if ((our_port->p_type&PORT_CLASS_mISDN_MASK) != PORT_CLASS_mISDN_DSS1)
3954 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: our port is not isdn.\n", ea_endpoint->ep_serial);
3957 our_pdss1 = (class Pdss1 *)our_port;
3959 /* find an endpoint that is on hold and has the same mISDNport that we are on */
3960 other_eapp = apppbx_first;
3963 if (other_eapp == this)
3965 other_eapp = other_eapp->next;
3968 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);
3969 if (other_eapp->e_terminal[0] /* has terminal */
3970 && other_eapp->ea_endpoint->ep_portlist /* has port */
3971 && other_eapp->ea_endpoint->ep_call_id) /* has call */
3973 other_port = find_port_id(other_eapp->ea_endpoint->ep_portlist->port_id);
3974 if (other_port) /* port still exists */
3976 if (other_port->p_type==PORT_TYPE_DSS1_NT_OUT
3977 || other_port->p_type==PORT_TYPE_DSS1_NT_IN) /* port is internal isdn */
3979 other_pdss1 = (class Pdss1 *)other_port;
3980 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);
3981 if (other_pdss1->p_m_hold /* port is on hold */
3982 && other_pdss1->p_m_mISDNport == our_pdss1->p_m_mISDNport /* same isdn interface */
3983 && other_pdss1->p_m_d_ces == our_pdss1->p_m_d_ces) /* same tei+sapi */
3987 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) comparing other endpoint's port is of other type!\n", ea_endpoint->ep_serial);
3991 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) comparing other endpoint's port doesn't exist enymore.\n", ea_endpoint->ep_serial);
3994 other_eapp = other_eapp->next;
3998 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: no other endpoint on same isdn interface with port on hold.\n", ea_endpoint->ep_serial);
4001 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) port on hold found.\n", ea_endpoint->ep_serial);
4003 /* if we have the same call */
4004 if (other_eapp->ea_endpoint->ep_call_id == ea_endpoint->ep_call_id)
4006 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: we an the other have the same call.\n", ea_endpoint->ep_serial);
4009 other_call = find_call_id(other_eapp->ea_endpoint->ep_call_id);
4012 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: other call doesn't exist anymore.\n", ea_endpoint->ep_serial);
4015 if (other_call->c_type != CALL_TYPE_PBX)
4017 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: other call is not a pbx call.\n", ea_endpoint->ep_serial);
4020 other_callpbx = (class CallPBX *)other_call;
4021 if (our_callpbx->c_partyline && other_callpbx->c_partyline)
4023 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: both calls are partylines.\n", ea_endpoint->ep_serial);
4027 /* remove relation to endpoint for call on hold */
4028 other_relation = other_callpbx->c_relation;
4029 other_relation_pointer = &other_callpbx->c_relation;
4030 while(other_relation)
4032 if (other_relation->epoint_id == other_eapp->ea_endpoint->ep_serial)
4034 /* detach other endpoint on hold */
4035 *other_relation_pointer = other_relation->next;
4036 memset(other_relation, 0, sizeof(struct call_relation));
4037 free(other_relation);
4039 other_relation = *other_relation_pointer;
4040 other_eapp->ea_endpoint->ep_call_id = NULL;
4044 /* change call/hold pointer of endpoint to the new call */
4045 temp_epoint = find_epoint_id(other_relation->epoint_id);
4048 if (temp_epoint->ep_call_id == other_call->c_serial)
4049 temp_epoint->ep_call_id = our_call->c_serial;
4052 other_relation_pointer = &other_relation->next;
4053 other_relation = other_relation->next;
4055 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) endpoint on hold removed, other enpoints on call relinked (to our call).\n", ea_endpoint->ep_serial);
4057 /* join call relations */
4058 our_relation = our_callpbx->c_relation;
4059 our_relation_pointer = &our_callpbx->c_relation;
4062 our_relation_pointer = &our_relation->next;
4063 our_relation = our_relation->next;
4065 *our_relation_pointer = other_callpbx->c_relation;
4066 other_callpbx->c_relation = NULL;
4067 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) relations joined.\n", ea_endpoint->ep_serial);
4069 /* release endpoint on hold */
4070 message = message_create(other_callpbx->c_serial, other_eapp->ea_endpoint->ep_serial, CALL_TO_EPOINT, MESSAGE_RELEASE);
4071 message->param.disconnectinfo.cause = CAUSE_NORMAL; /* normal */
4072 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
4073 message_put(message);
4075 /* if we are not a partyline, we get partyline state from other call */
4076 our_callpbx->c_partyline += other_callpbx->c_partyline;
4078 /* remove empty call */
4080 PDEBUG(DEBUG_EPOINT, "EPOINT(%d)d-call completely removed!\n");
4082 /* mixer must update */
4083 our_callpbx->c_mixer = 1; /* update mixer flag */
4085 /* we send a retrieve to that endpoint */
4086 // mixer will update the hold-state of the call and send it to the endpoints is changes
4090 /* check if we have an external call
4091 * this is used to check for encryption ability
4093 int EndpointAppPBX::check_external(char **errstr, class Port **port)
4095 struct call_relation *relation;
4097 class CallPBX *callpbx;
4098 class Endpoint *epoint;
4100 /* some paranoia check */
4101 if (!ea_endpoint->ep_portlist)
4103 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) error: we have no port.\n", ea_endpoint->ep_serial);
4104 *errstr = "No Call";
4109 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) error: we are not internal extension.\n", ea_endpoint->ep_serial);
4110 *errstr = "No Call";
4114 /* check if we have a call with 2 parties */
4115 call = find_call_id(ea_endpoint->ep_call_id);
4118 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) we have currently no call.\n", ea_endpoint->ep_serial);
4119 *errstr = "No Call";
4122 if (call->c_type != CALL_TYPE_PBX)
4124 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call is nto a pbx call.\n", ea_endpoint->ep_serial);
4125 *errstr = "No PBX Call";
4128 callpbx = (class CallPBX *)call;
4129 relation = callpbx->c_relation;
4132 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call has no relation.\n", ea_endpoint->ep_serial);
4133 *errstr = "No Call";
4136 if (!relation->next)
4138 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call has no 2nd relation.\n", ea_endpoint->ep_serial);
4139 *errstr = "No Call";
4142 if (relation->next->next)
4144 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call has more than two relations.\n", ea_endpoint->ep_serial);
4145 *errstr = "Err: Conference";
4148 if (relation->epoint_id == ea_endpoint->ep_serial)
4150 relation = relation->next;
4151 if (relation->epoint_id == ea_endpoint->ep_serial)
4153 PERROR("EPOINT(%d) SOFTWARE ERROR: both call relations are related to our endpoint.\n", ea_endpoint->ep_serial);
4154 *errstr = "Software Error";
4159 /* check remote port for external call */
4160 epoint = find_epoint_id(relation->epoint_id);
4163 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call has no 2nd endpoint.\n", ea_endpoint->ep_serial);
4164 *errstr = "No Call";
4167 if (!epoint->ep_portlist)
4169 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) 2nd endpoint has not port.\n", ea_endpoint->ep_serial);
4170 *errstr = "No Call";
4173 *port = find_port_id(epoint->ep_portlist->port_id);
4176 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) 2nd endpoint has an none existing port.\n", ea_endpoint->ep_serial);
4177 *errstr = "No Call";
4180 if (((*port)->p_type&PORT_CLASS_mISDN_MASK)!=PORT_CLASS_mISDN_DSS1) /* port is not external isdn */
4182 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) 2nd endpoint has not an external port.\n", ea_endpoint->ep_serial);
4183 *errstr = "No Ext Call";
4186 if ((*port)->p_state != PORT_STATE_CONNECT)
4188 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) 2nd endpoint's port is not in connected state.\n", ea_endpoint->ep_serial);
4189 *errstr = "No Ext Connect";
4195 void EndpointAppPBX::logmessage(struct message *message)
4199 char *logtext = "unknown";
4202 if (message->flow != EPOINT_TO_PORT)
4204 PERROR("EPOINT(%d) message not of correct flow type-\n", ea_endpoint->ep_serial);
4208 switch(message->type)
4211 port = find_port_id(message->id_to);
4214 if (port->p_type == PORT_TYPE_DSS1_NT_OUT)
4216 pdss1 = (class Pdss1 *)port;
4217 printlog("%3d outgoing SETUP from %s='%s'%s%s%s%s to intern='%s' port='%d' (NT)\n",
4218 ea_endpoint->ep_serial,
4219 (message->param.setup.callerinfo.intern[0])?"intern":"extern",
4220 (message->param.setup.callerinfo.intern[0])?e_callerinfo.intern:e_callerinfo.id,
4221 (message->param.setup.callerinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
4222 (message->param.setup.redirinfo.id[0])?"redirected='":"",
4223 message->param.setup.redirinfo.id,
4224 (message->param.setup.redirinfo.id[0])?"'":"",
4225 message->param.setup.dialinginfo.number,
4226 pdss1->p_m_mISDNport->portnum
4229 if (port->p_type == PORT_TYPE_DSS1_TE_OUT)
4231 pdss1 = (class Pdss1 *)port;
4232 printlog("%3d outgoing SETUP from %s='%s'%s%s%s%s to extern='%s' port='%d' (TE)\n",
4233 ea_endpoint->ep_serial,
4234 (message->param.setup.callerinfo.intern[0])?"intern":"extern",
4235 (message->param.setup.callerinfo.intern[0])?e_callerinfo.intern:e_callerinfo.id,
4236 (message->param.setup.callerinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
4237 (message->param.setup.redirinfo.id[0])?"redirected='":"",
4238 message->param.setup.redirinfo.id,
4239 (message->param.setup.redirinfo.id[0])?"'":"",
4240 message->param.setup.dialinginfo.number,
4241 pdss1->p_m_mISDNport->portnum
4244 if (port->p_type == PORT_TYPE_H323_OUT)
4246 printlog("%3d outgoing SETUP from %s='%s'%s%s%s%s to h323='%s'\n",
4247 ea_endpoint->ep_serial,
4248 (message->param.setup.callerinfo.intern[0])?"intern":"extern",
4249 (message->param.setup.callerinfo.intern[0])?e_callerinfo.intern:e_callerinfo.id,
4250 (message->param.setup.callerinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
4251 (message->param.setup.redirinfo.id[0])?"redirected='":"",
4252 message->param.setup.redirinfo.id,
4253 (message->param.setup.redirinfo.id[0])?"'":"",
4254 message->param.setup.dialinginfo.number
4257 if (port->p_type == PORT_TYPE_SIP_OUT)
4259 printlog("%3d outgoing SETUP from %s='%s'%s%s%s%s to sip='%s'\n",
4260 ea_endpoint->ep_serial,
4261 (message->param.setup.callerinfo.intern[0])?"intern":"extern",
4262 (message->param.setup.callerinfo.intern[0])?e_callerinfo.intern:e_callerinfo.id,
4263 (message->param.setup.callerinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
4264 (message->param.setup.redirinfo.id[0])?"redirected='":"",
4265 message->param.setup.redirinfo.id,
4266 (message->param.setup.redirinfo.id[0])?"'":"",
4267 message->param.setup.dialinginfo.number
4270 if (port->p_type == PORT_TYPE_VBOX_OUT)
4272 printlog("%3d outgoing SETUP from %s='%s'%s%s%s%s to vbox='%s'\n",
4273 ea_endpoint->ep_serial,
4274 (message->param.setup.callerinfo.intern[0])?"intern":"extern",
4275 (message->param.setup.callerinfo.intern[0])?e_callerinfo.intern:e_callerinfo.id,
4276 (message->param.setup.callerinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
4277 (message->param.setup.redirinfo.id[0])?"redirected='":"",
4278 message->param.setup.redirinfo.id,
4279 (message->param.setup.redirinfo.id[0])?"'":"",
4280 message->param.setup.dialinginfo.number
4285 case MESSAGE_OVERLAP:
4286 printlog("%3d outgoing SETUP ACKNOWLEDGE\n",
4287 ea_endpoint->ep_serial
4291 case MESSAGE_PROCEEDING:
4292 printlog("%3d outgoing PROCEEDING\n",
4293 ea_endpoint->ep_serial
4297 case MESSAGE_ALERTING:
4298 printlog("%3d outgoing ALERTING\n",
4299 ea_endpoint->ep_serial
4303 case MESSAGE_CONNECT:
4304 printlog("%3d outgoing CONNECT id='%s'%s\n",
4305 ea_endpoint->ep_serial,
4306 message->param.connectinfo.id,
4307 (message->param.connectinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":""
4311 case MESSAGE_DISCONNECT:
4312 printlog("%3d outgoing DISCONNECT cause='%d' (%s) location='%d' (%s) display='%s'\n",
4313 ea_endpoint->ep_serial,
4314 message->param.disconnectinfo.cause,
4315 (message->param.disconnectinfo.cause>0 && message->param.disconnectinfo.cause<128)?isdn_cause[message->param.disconnectinfo.cause].english:"-",
4316 message->param.disconnectinfo.location,
4317 (message->param.disconnectinfo.location>=0 && message->param.disconnectinfo.location<16)?isdn_location[message->param.disconnectinfo.location].english:"-",
4318 message->param.disconnectinfo.display
4322 case MESSAGE_RELEASE:
4323 printlog("%3d outgoing RELEASE cause='%d' (%s) location='%d' (%s)\n",
4324 ea_endpoint->ep_serial,
4325 message->param.disconnectinfo.cause,
4326 (message->param.disconnectinfo.cause>0 && message->param.disconnectinfo.cause<128)?isdn_cause[message->param.disconnectinfo.cause].english:"-",
4327 message->param.disconnectinfo.location,
4328 (message->param.disconnectinfo.location>=0 && message->param.disconnectinfo.location<16)?isdn_location[message->param.disconnectinfo.location].english:"-"
4332 case MESSAGE_NOTIFY:
4333 switch(message->param.notifyinfo.notify)
4339 logtext = "USER_SUSPENDED";
4342 logtext = "BEARER_SERVICE_CHANGED";
4345 logtext = "USER_RESUMED";
4348 logtext = "CONFERENCE_ESTABLISHED";
4351 logtext = "CONFERENCE_DISCONNECTED";
4354 logtext = "OTHER_PARTY_ADDED";
4357 logtext = "ISOLATED";
4360 logtext = "REATTACHED";
4363 logtext = "OTHER_PARTY_ISOLATED";
4366 logtext = "OTHER_PARTY_REATTACHED";
4369 logtext = "OTHER_PARTY_SPLIT";
4372 logtext = "OTHER_PARTY_DISCONNECTED";
4375 logtext = "CONFERENCE_FLOATING";
4378 logtext = "CONFERENCE_DISCONNECTED_PREEMTED";
4381 logtext = "CONFERENCE_FLOATING_SERVED_USER_PREEMTED";
4384 logtext = "CALL_IS_A_WAITING_CALL";
4387 logtext = "DIVERSION_ACTIVATED";
4390 logtext = "RESERVED_CT_1";
4393 logtext = "RESERVED_CT_2";
4396 logtext = "REVERSE_CHARGING";
4399 logtext = "REMOTE_HOLD";
4402 logtext = "REMOTE_RETRIEVAL";
4405 logtext = "CALL_IS_DIVERTING";
4408 SPRINT(buffer, "indicator=%d", message->param.notifyinfo.notify - 0x80);
4412 printlog("%3d outgoing NOTIFY notify='%s' id='%s'%s display='%s'\n",
4413 ea_endpoint->ep_serial,
4415 message->param.notifyinfo.id,
4416 (message->param.notifyinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
4417 message->param.notifyinfo.display
4421 case MESSAGE_INFORMATION:
4422 printlog("%3d outgoing INFORMATION information='%s'\n",
4423 ea_endpoint->ep_serial,
4424 message->param.information.number
4428 case MESSAGE_FACILITY:
4429 printlog("%3d outgoing FACILITY len='%d'\n",
4430 ea_endpoint->ep_serial,
4431 message->param.facilityinfo.len
4436 printlog("%3d outgoing TONE dir='%s' name='%s'\n",
4437 ea_endpoint->ep_serial,
4438 message->param.tone.dir,
4439 message->param.tone.name
4444 PERROR("EPOINT(%d) message not of correct type (%d)\n", ea_endpoint->ep_serial, message->type);
4448 void EndpointAppPBX::message_disconnect_port(struct port_list *portlist, int cause, int location, char *display)
4450 struct message *message;
4454 if (!portlist->port_id)
4457 if (!e_connectedmode)
4459 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_DISCONNECT);
4460 message->param.disconnectinfo.cause = cause;
4461 message->param.disconnectinfo.location = location;
4463 SCPY(message->param.disconnectinfo.display, display);
4465 SCPY(message->param.disconnectinfo.display, get_isdn_cause(cause, location, e_ext.display_cause));
4468 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
4470 SCPY(message->param.notifyinfo.display, display);
4472 SCPY(message->param.notifyinfo.display, get_isdn_cause(cause, location, e_ext.display_cause));
4474 message_put(message);
4475 logmessage(message);