1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** all actions (and hangup) are processed here **
10 \*****************************************************************************/
18 #include "linux/isdnif.h"
20 extern char **environ;
23 /* create caller id from digits by comparing with national and international
26 char *nationalize_callerinfo(char *string, int *ntype)
28 if (!strncmp(options.international, string, strlen(options.international)))
30 *ntype = INFO_NTYPE_INTERNATIONAL;
31 return(string+strlen(options.international));
33 if (!strncmp(options.national, string, strlen(options.national)))
35 *ntype = INFO_NTYPE_NATIONAL;
36 return(string+strlen(options.national));
38 *ntype = INFO_NTYPE_SUBSCRIBER;
42 /* create number (including access codes) from caller id
45 char *numberrize_callerinfo(char *string, int ntype)
47 static char result[256];
51 case INFO_NTYPE_INTERNATIONAL:
52 UCPY(result, options.international);
57 case INFO_NTYPE_NATIONAL:
58 UCPY(result, options.national);
70 * process init 'internal' / 'external' / 'h323' / 'chan' / 'vbox-record' / 'partyline'...
72 void EndpointAppPBX::_action_init_call(int chan)
75 struct port_list *portlist = ea_endpoint->ep_portlist;
77 /* a created call, this should never happen */
78 if (ea_endpoint->ep_call_id)
80 if (options.deb & DEBUG_EPOINT)
81 PERROR("EPOINT(%d): We already have a call instance, this should never happen!\n", ea_endpoint->ep_serial);
86 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): Creating new call instance.\n", ea_endpoint->ep_serial);
88 call = new CallChan(ea_endpoint);
90 call = new CallPBX(ea_endpoint);
93 /* resource not available */
94 message_disconnect_port(portlist, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL, "");
95 new_state(EPOINT_STATE_OUT_DISCONNECT);
96 set_tone(portlist,"cause_22");
99 ea_endpoint->ep_call_id = call->c_serial;
101 void EndpointAppPBX::action_init_call(void)
103 _action_init_call(0);
105 void EndpointAppPBX::action_init_chan(void)
107 _action_init_call(1);
111 * process dialing 'internal'
113 void EndpointAppPBX::action_dialing_internal(void)
115 struct capa_info capainfo;
116 struct caller_info callerinfo;
117 struct redir_info redirinfo;
118 struct dialing_info dialinginfo;
119 struct port_list *portlist = ea_endpoint->ep_portlist;
120 struct message *message;
121 struct extension ext;
122 struct route_param *rparam;
124 /* send proceeding, because number is complete */
125 set_tone(portlist, "proceeding");
126 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
127 message_put(message);
129 new_state(EPOINT_STATE_IN_PROCEEDING);
131 /* create bearer/caller/dialinginfo */
132 memcpy(&capainfo, &e_capainfo, sizeof(capainfo));
133 memcpy(&callerinfo, &e_callerinfo, sizeof(callerinfo));
134 memcpy(&redirinfo, &e_redirinfo, sizeof(redirinfo));
135 memset(&dialinginfo, 0, sizeof(dialinginfo));
136 dialinginfo.itype = INFO_ITYPE_INTERN;
137 SCPY(dialinginfo.number, e_dialinginfo.number);
139 /* process extension */
140 if ((rparam = routeparam(e_action, PARAM_EXTENSION)))
141 SCPY(dialinginfo.number, rparam->string_value);
143 /* process number type */
144 if ((rparam = routeparam(e_action, PARAM_TYPE)))
145 dialinginfo.ntype = rparam->integer_value;
147 /* process service */
148 if ((rparam = routeparam(e_action, PARAM_CAPA)))
150 capainfo.bearer_capa = rparam->integer_value;
151 if (capainfo.bearer_capa != INFO_BC_SPEECH
152 && capainfo.bearer_capa != INFO_BC_AUDIO)
154 capainfo.bearer_mode = INFO_BMODE_PACKET;
156 capainfo.bearer_info1 = INFO_INFO1_NONE;
158 if ((rparam = routeparam(e_action, PARAM_BMODE)))
160 capainfo.bearer_mode = rparam->integer_value;
162 if ((rparam = routeparam(e_action, PARAM_INFO1)))
164 capainfo.bearer_info1 = rparam->integer_value;
166 if ((rparam = routeparam(e_action, PARAM_HLC)))
168 capainfo.hlc = rparam->integer_value;
170 if ((rparam = routeparam(e_action, PARAM_EXTHLC)))
172 capainfo.exthlc = rparam->integer_value;
175 /* process presentation */
176 if ((rparam = routeparam(e_action, PARAM_PRESENT)))
178 callerinfo.present = (rparam->integer_value)?INFO_PRESENT_ALLOWED:INFO_PRESENT_RESTRICTED;
181 /* check if extension exists AND only if not multiple extensions */
182 if (!read_extension(&ext, dialinginfo.number) && !strchr(dialinginfo.number,','))
184 printlog("%3d action INTERN dialed extension %s doesn't exist.\n", ea_endpoint->ep_serial, dialinginfo.number);
185 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): extension %s doesn't exist\n", ea_endpoint->ep_serial, dialinginfo.number);
186 new_state(EPOINT_STATE_OUT_DISCONNECT);
187 message_disconnect_port(portlist, CAUSE_UNALLOCATED, LOCATION_PRIVATE_LOCAL, "");
188 set_tone(portlist, "cause_86");
191 /* check if internal calls are denied */
192 if (e_ext.rights < 1)
194 printlog("%3d action INTERN access to internal phones are denied for this caller.\n", ea_endpoint->ep_serial);
195 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): internal call from terminal %s denied.\n", ea_endpoint->ep_serial, e_terminal);
196 new_state(EPOINT_STATE_OUT_DISCONNECT);
197 message_disconnect_port(portlist, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, "");
198 set_tone(portlist, "cause_81");
202 /* add or update internal call */
203 printlog("%3d action INTERN call to extension %s.\n", ea_endpoint->ep_serial, dialinginfo.number);
204 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_SETUP);
205 memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
206 memcpy(&message->param.setup.redirinfo, &redirinfo, sizeof(struct redir_info));
207 memcpy(&message->param.setup.callerinfo, &callerinfo, sizeof(struct caller_info));
208 memcpy(&message->param.setup.capainfo, &capainfo, sizeof(struct capa_info));
209 message_put(message);
212 /* process dialing external
214 void EndpointAppPBX::action_dialing_external(void)
216 struct capa_info capainfo;
217 struct caller_info callerinfo;
218 struct redir_info redirinfo;
219 struct dialing_info dialinginfo;
221 struct port_list *portlist = ea_endpoint->ep_portlist;
222 struct message *message;
223 struct route_param *rparam;
225 /* special processing of delete characters '*' and '#' */
226 if (e_ext.delete_ext)
228 /* dialing a # causes a clearing of complete number */
229 if (strchr(e_extdialing, '#'))
231 e_extdialing[0] = '\0';
232 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): '#' detected: terminal '%s' selected caller id '%s' and continues dialing: '%s'\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id, e_extdialing);
234 /* eliminate digits before '*', which is a delete digit
236 if (strchr(e_extdialing, '*'))
239 while((p=strchr(e_extdialing, '*')))
241 if (p > e_extdialing) /* only if there is a digit in front */
246 UCPY(p, p+1); /* remove '*' */
248 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s deleted digits and got new string: %s\n", ea_endpoint->ep_serial, e_terminal, e_extdialing);
252 /* create bearer/caller/dialinginfo */
253 memcpy(&capainfo, &e_capainfo, sizeof(capainfo));
254 memcpy(&callerinfo, &e_callerinfo, sizeof(callerinfo));
255 memcpy(&redirinfo, &e_redirinfo, sizeof(redirinfo));
256 memset(&dialinginfo, 0, sizeof(dialinginfo));
257 dialinginfo.itype = INFO_ITYPE_EXTERN;
258 dialinginfo.sending_complete = 0;
259 SCPY(dialinginfo.number, e_extdialing);
262 if ((rparam = routeparam(e_action, PARAM_PREFIX)))
263 SPRINT(dialinginfo.number, "%s%s", rparam->string_value, e_extdialing);
265 /* process number complete */
266 if ((rparam = routeparam(e_action, PARAM_COMPLETE)))
267 if ((rparam = routeparam(e_action, PARAM_PREFIX)))
268 SCPY(dialinginfo.number, rparam->string_value);
269 dialinginfo.sending_complete = 1;
271 /* process number type */
272 if ((rparam = routeparam(e_action, PARAM_TYPE)))
273 dialinginfo.ntype = rparam->integer_value;
275 /* process service */
276 if ((rparam = routeparam(e_action, PARAM_CAPA)))
278 capainfo.bearer_capa = rparam->integer_value;
279 if (capainfo.bearer_capa != INFO_BC_SPEECH
280 && capainfo.bearer_capa != INFO_BC_AUDIO)
282 capainfo.bearer_mode = INFO_BMODE_PACKET;
284 capainfo.bearer_info1 = INFO_INFO1_NONE;
286 if ((rparam = routeparam(e_action, PARAM_BMODE)))
288 capainfo.bearer_mode = rparam->integer_value;
290 if ((rparam = routeparam(e_action, PARAM_INFO1)))
292 capainfo.bearer_info1 = rparam->integer_value;
294 if ((rparam = routeparam(e_action, PARAM_HLC)))
296 capainfo.hlc = rparam->integer_value;
298 if ((rparam = routeparam(e_action, PARAM_EXTHLC)))
300 capainfo.exthlc = rparam->integer_value;
304 /* process callerid */
305 if ((rparam = routeparam(e_action, PARAM_CALLERID)))
307 SCPY(callerinfo.id, rparam->string_value);
309 if ((rparam = routeparam(e_action, PARAM_CALLERIDTYPE)))
311 callerinfo.ntype = rparam->integer_value;
314 /* process presentation */
315 if ((rparam = routeparam(e_action, PARAM_PRESENT)))
317 callerinfo.present = (rparam->integer_value)?INFO_PRESENT_ALLOWED:INFO_PRESENT_RESTRICTED;
320 /* process interfaces */
321 if ((rparam = routeparam(e_action, PARAM_INTERFACES)))
322 SCPY(dialinginfo.interfaces, rparam->string_value);
324 /* check if local calls are denied */
325 if (e_ext.rights < 2)
327 printlog("%3d action EXTERN calls are denied for this caller.\n", ea_endpoint->ep_serial);
328 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): external call from terminal denied: %s\n", ea_endpoint->ep_serial, e_terminal);
329 release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, 0);
330 set_tone(portlist, "cause_82");
332 message_disconnect_port(portlist, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, "");
333 new_state(EPOINT_STATE_OUT_DISCONNECT);
337 if (!strncmp(dialinginfo.number, options.national, strlen(options.national))
338 || dialinginfo.ntype == INFO_NTYPE_NATIONAL
339 || dialinginfo.ntype == INFO_NTYPE_INTERNATIONAL)
341 /* check if national calls are denied */
342 if (e_ext.rights < 3)
344 printlog("%3d action EXTERN national calls are denied for this caller.\n", ea_endpoint->ep_serial);
345 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): national call from terminal %s denied.\n", ea_endpoint->ep_serial, e_terminal);
346 release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, 0);
347 set_tone(portlist, "cause_83");
352 if (!strncmp(dialinginfo.number, options.international, strlen(options.international))
353 || dialinginfo.ntype == INFO_NTYPE_INTERNATIONAL)
355 /* check if international calls are denied */
356 if (e_ext.rights < 4)
358 printlog("%3d action EXTERN international calls are denied for this caller.\n", ea_endpoint->ep_serial);
359 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): international call from terminal %s denied.\n", ea_endpoint->ep_serial, e_terminal);
360 release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, 0);
361 set_tone(portlist, "cause_84");
366 /* add or update outgoing call */
367 printlog("%3d action EXTERN call to destination %s.\n", ea_endpoint->ep_serial, dialinginfo.number);
368 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_SETUP);
369 memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
370 memcpy(&message->param.setup.redirinfo, &redirinfo, sizeof(struct redir_info));
371 memcpy(&message->param.setup.callerinfo, &callerinfo, sizeof(struct caller_info));
372 memcpy(&message->param.setup.capainfo, &capainfo, sizeof(struct capa_info));
373 message_put(message);
379 * process dialing h323
381 #define set_ip_macro \
382 UNCPY(helpbuffer, address, sizeof(helpbuffer)); \
383 helpbuffer[sizeof(helpbuffer)-1] = '\0'; \
384 UNPRINT(helpbuffer + (int)(address - dial), sizeof(helpbuffer)-1 - (int)(address - dial), "%d.%d.%d.%d", ip_a, ip_b, ip_c, ip_d); \
385 ii = strlen(helpbuffer); \
386 UNCAT(helpbuffer, dial+i, sizeof(helpbuffer)-1); \
387 dial = address + ii; \
389 UCPY(address, helpbuffer);
390 #define set_port_macro \
391 UNCPY(helpbuffer, address, sizeof(helpbuffer)); \
392 helpbuffer[sizeof(helpbuffer)-1] = '\0'; \
393 UNPRINT(helpbuffer + (int)(address - dial), sizeof(helpbuffer)-1 - (int)(address - dial), "%d", port); \
394 ii = strlen(helpbuffer); \
395 UNCAT(helpbuffer, dial+i, sizeof(helpbuffer)-1); \
396 dial = address + ii; \
398 UCPY(address, helpbuffer);
399 void EndpointAppPBX::action_dialing_h323(void)
401 struct message *message;
402 struct dialing_info dialinginfo;
404 struct port_list *portlist = ea_endpoint->ep_portlist;
406 char address_buffer[256], *address=address_buffer;
408 int ip_a=0, ip_b=0, ip_c=0, ip_d=0, port=0;
409 struct route_param *rparam;
410 char helpbuffer[128];
412 /* check if address parameter is given */
413 if ((rparam = routeparam(e_action, PARAM_ADDRESS)))
415 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): complete address is given by parameter: '%s'\n", ea_endpoint->ep_serial, rparam->string_value);
416 SCPY(address_buffer, rparam->string_value);
417 goto address_complete;
420 /* check for given host */
421 if ((rparam = routeparam(e_action, PARAM_HOST)))
422 if (rparam->string_value[0])
424 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): host is given by parameter: '%s'\n", ea_endpoint->ep_serial, rparam->string_value);
425 SCPY(host, rparam->string_value);
426 if ((rparam = routeparam(e_action, PARAM_PORT)))
428 if (rparam->integer_value>0 && rparam->integer_value<65536)
430 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): port is given with the host by parameter: %d\n", ea_endpoint->ep_serial, rparam->integer_value);
431 if (strlen(host)+7 < sizeof(host))
432 UPRINT(host, ":%d/", rparam->integer_value);
443 /* include prefix and put 'host'(port) in front */
444 if ((rparam = routeparam(e_action, PARAM_PREFIX)))
446 SPRINT(address_buffer, "%s%s%s", host, rparam->string_value, e_extdialing);
451 SPRINT(address_buffer, "%s%s", host, e_extdialing);
452 printf("address:%s host %s extdialing %s\n",address,host, e_extdialing);
454 address = e_extdialing;
460 /* check for ip-number only with numerical digits (can be dialed by any phone) */
463 dial = address + strlen(host);
464 goto check_user; /* we have complete host (port) */
470 return; /* unfinished */
471 if (dial[i]<'0' || dial[i]>'9')
477 ip_a = (dial[0]-'0')*100 + (dial[1]-'0')*10 + (dial[2]-'0');
481 printlog("%3d action H323 address '%s' is invalid.\n", ea_endpoint->ep_serial, address);
482 message_disconnect_port(portlist, CAUSE_INVALID, LOCATION_PRIVATE_LOCAL, "");
483 new_state(EPOINT_STATE_OUT_DISCONNECT);
484 set_tone(portlist,"cause_1c");
490 ip_b = (dial[3]-'0')*100 + (dial[4]-'0')*10 + (dial[5]-'0');
496 ip_c = (dial[6]-'0')*100 + (dial[7]-'0')*10 + (dial[8]-'0');
502 ip_d = (dial[9]-'0')*100 + (dial[10]-'0')*10 + (dial[11]-'0');
506 if (i==4 || i==7 || i==10)
511 if (i==5 || i==8 || i==11)
513 if (dial[i-2]=='2' && dial[i-1]>'5')
517 UPRINT(address, "%d.%d.%d.%d", ip_a, ip_b, ip_c, ip_d);
519 goto address_complete;
521 /* there are three stages of dialing: 1. ip, 2. port, 3. user, let's find out where we at */
523 if (strchr(address, '@'))
525 dial = strchr(address, '\0');
526 goto address_complete;
528 if (strchr(address, ':'))
530 dial = strchr(address, ':') + 1;
533 if (strchr(address, '/'))
535 dial = strchr(address, '/') + 1;
539 /* get ip from ip-number */
540 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): checking dialed for ip: %s\n", ea_endpoint->ep_serial, dial);
541 ip_a = ip_b = ip_c = ip_d = 0;
550 if (dial[i]>='0' && dial[i]<='9')
551 ip_a = (ip_a*10) + dial[i]-'0';
552 else if (dial[i]=='.' || dial[i]=='*')
555 // if (i && dial[i-1]=='.')
557 // /* add 0 if two dots */
558 // UCPY(dial+i+1, dial+i);
565 else if (dial[i]=='#')
572 goto address_complete;
574 else if (dial[i] == '\0')
576 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): ip so far: %d*\n", ea_endpoint->ep_serial, ip_a);
591 if (dial[i]>='0' && dial[i]<='9')
592 ip_b = (ip_b*10) + dial[i]-'0';
593 else if (dial[i]=='.' || dial[i]=='*')
599 else if (dial[i]=='#')
606 goto address_complete;
608 else if (dial[i] == '\0')
610 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): ip so far: %d.%d*\n", ea_endpoint->ep_serial, ip_a, ip_b);
625 if (dial[i]>='0' && dial[i]<='9')
626 ip_c = (ip_c*10) + dial[i]-'0';
627 else if (dial[i]=='.' || dial[i]=='*')
633 else if (dial[i]=='#')
640 goto address_complete;
642 else if (dial[i] == '\0')
644 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): ip so far: %d.%d.%d\n", ea_endpoint->ep_serial, ip_a, ip_b, ip_c);
659 if (dial[i]>='0' && dial[i]<='9')
660 ip_d = (ip_d*10) + dial[i]-'0';
661 else if (dial[i]=='*' || dial[i]==':')
669 else if (dial[i]=='#')
674 goto address_complete;
676 else if (dial[i] == '\0')
678 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): ip so far: %d.%d.%d.%d*\n", ea_endpoint->ep_serial, ip_a, ip_b, ip_c, ip_d);
689 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): checking dialed for port: %s\n", ea_endpoint->ep_serial, dial);
699 if (dial[i]>='0' && dial[i]<='9')
700 port = (port*10) + dial[i]-'0';
701 else if (dial[i]=='*' || dial[i]=='/')
703 if (i) /* only if there is something entered */
710 UCPY(dial+i, dial+i+1);
717 else if (dial[i]=='#')
722 goto address_complete;
724 else if (dial[i] == '\0')
726 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): h323 address so far: %s\n", ea_endpoint->ep_serial, address);
737 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): checking dialed for user: %s\n", ea_endpoint->ep_serial, dial);
746 /* convert to @-notation */
747 SCPY(helpbuffer, strchr(address, '/')+1);
748 SCAT(helpbuffer, "@");
749 *strchr(address, '/') = '\0';
750 SCAT(helpbuffer, address);
751 UCPY(address, helpbuffer);
752 goto address_complete;
754 else if (dial[i] == '\0')
756 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): h323 address so far: %s\n", ea_endpoint->ep_serial, address);
764 /* send proceeding, because number is complete */
765 set_tone(portlist, "proceeding");
766 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
767 message_put(message);
769 new_state(EPOINT_STATE_IN_PROCEEDING);
771 memset(&dialinginfo, 0, sizeof(dialinginfo));
772 dialinginfo.itype = INFO_ITYPE_H323;
773 dialinginfo.sending_complete = 1;
774 SPRINT(dialinginfo.number, "%s", address);
775 /* strip the # at the end */
776 if (dialinginfo.number[0])
777 if (dialinginfo.number[strlen(dialinginfo.number)-1] == '#')
778 dialinginfo.number[strlen(dialinginfo.number)-1] = '\0';
780 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): complete multi-dial string \"%s\"\n", ea_endpoint->ep_serial, dialinginfo.number);
782 /* add or update internal call */
783 printlog("%3d action H323 call to address %s.\n", ea_endpoint->ep_serial, dialinginfo.number);
784 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_SETUP);
785 memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
786 memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
787 memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
788 memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
789 message_put(message);
792 void EndpointAppPBX::action_dialing_h323(void)
794 struct port_list *portlist = ea_endpoint->ep_portlist;
796 printlog("%3d action H323 stack not implemented.\n", ea_endpoint->ep_serial);
797 message_disconnect_port(portlist, CAUSE_UNIMPLEMENTED, LOCATION_PRIVATE_LOCAL, "");
798 new_state(EPOINT_STATE_OUT_DISCONNECT);
799 set_tone(portlist,"cause_4f");
803 void EndpointAppPBX::action_dialing_chan(void)
805 struct port_list *portlist = ea_endpoint->ep_portlist;
807 printlog("%3d action channel API not implemented.\n", ea_endpoint->ep_serial);
808 message_disconnect_port(portlist, CAUSE_UNIMPLEMENTED, LOCATION_PRIVATE_LOCAL, "");
809 new_state(EPOINT_STATE_OUT_DISCONNECT);
810 set_tone(portlist,"cause_4f");
815 * process dialing the "am" and record
817 void EndpointAppPBX::action_dialing_vbox_record(void)
819 struct dialing_info dialinginfo;
820 struct port_list *portlist = ea_endpoint->ep_portlist;
821 struct message *message;
822 struct extension ext;
823 struct route_param *rparam;
825 portlist = ea_endpoint->ep_portlist;
827 /* check for given extension */
828 if (!(rparam = routeparam(e_action, PARAM_EXTENSION)))
830 printlog("%3d action VBOX-RECORD extension not given by parameter.\n", ea_endpoint->ep_serial);
831 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): cannot record, because no 'extension' parameter has been specified.\n", ea_endpoint->ep_serial);
833 new_state(EPOINT_STATE_OUT_DISCONNECT);
834 message_disconnect_port(portlist, CAUSE_SERVICEUNAVAIL, LOCATION_PRIVATE_LOCAL, "");
835 set_tone(portlist, "cause_3f");
839 /* check if extension exists */
840 if (!read_extension(&ext, rparam->string_value))
842 printlog("%3d action VBOX-RECORD given extension %s doesn't exist.\n", ea_endpoint->ep_serial, rparam->string_value);
843 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): extension %s doesn't exist\n", ea_endpoint->ep_serial, rparam->string_value);
844 new_state(EPOINT_STATE_OUT_DISCONNECT);
845 message_disconnect_port(portlist, CAUSE_UNALLOCATED, LOCATION_PRIVATE_LOCAL, "");
846 set_tone(portlist, "cause_86");
850 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s dialing extension: %s\n", ea_endpoint->ep_serial, e_terminal, rparam->string_value);
852 /* check if internal calls are denied */
853 if (e_ext.rights < 1)
855 printlog("%3d action VBOX-RECORD calls are denied for this caller.\n", ea_endpoint->ep_serial);
856 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): internal call from terminal %s denied.\n", ea_endpoint->ep_serial, e_terminal);
857 new_state(EPOINT_STATE_OUT_DISCONNECT);
858 message_disconnect_port(portlist, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, "");
859 set_tone(portlist, "cause_81");
863 set_tone(portlist, "proceeding");
864 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
865 message_put(message);
867 new_state(EPOINT_STATE_IN_PROCEEDING);
869 memset(&dialinginfo, 0, sizeof(dialinginfo));
870 dialinginfo.itype = INFO_ITYPE_VBOX;
871 dialinginfo.sending_complete = 1;
872 SCPY(dialinginfo.number, rparam->string_value);
874 /* append special announcement (if given) */
875 if ((rparam = routeparam(e_action, PARAM_ANNOUNCEMENT)))
876 if (rparam->string_value[0])
878 SCAT(dialinginfo.number, ",");
879 SCAT(dialinginfo.number, rparam->string_value);
882 /* add or update internal call */
883 printlog("%3d action VBOX-RECORD call to extension %s.\n", ea_endpoint->ep_serial, dialinginfo.number);
884 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_SETUP);
885 memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
886 memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
887 memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
888 memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
889 message_put(message);
896 void EndpointAppPBX::action_init_partyline(void)
899 class CallPBX *callpbx;
900 struct port_list *portlist = ea_endpoint->ep_portlist;
901 struct message *message;
902 struct route_param *rparam;
904 struct call_relation *relation;
906 portlist = ea_endpoint->ep_portlist;
908 /* check for given extension */
909 if (!(rparam = routeparam(e_action, PARAM_ROOM)))
911 printlog("%3d action PARTYLINE no 'room' parameter given at routing.\n", ea_endpoint->ep_serial);
912 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): missing parameter 'room'.\n", ea_endpoint->ep_serial);
914 new_state(EPOINT_STATE_OUT_DISCONNECT);
915 message_disconnect_port(portlist, CAUSE_SERVICEUNAVAIL, LOCATION_PRIVATE_LOCAL, "");
916 set_tone(portlist, "cause_3f");
919 if (rparam->integer_value <= 0)
921 printlog("%3d action PARTYLINE 'room' value must be greate 0.\n", ea_endpoint->ep_serial);
922 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): invalid value for 'room'.\n", ea_endpoint->ep_serial);
925 partyline = rparam->integer_value;
927 /* don't create call if partyline exists */
931 if (call->c_type == CALL_TYPE_PBX)
933 callpbx = (class CallPBX *)call;
934 if (callpbx->c_partyline == rparam->integer_value)
942 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): Creating new call instance.\n", ea_endpoint->ep_serial);
943 if (!(call = new CallPBX(ea_endpoint)))
946 /* resource not available */
947 message_disconnect_port(portlist, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL, "");
948 new_state(EPOINT_STATE_OUT_DISCONNECT);
949 set_tone(portlist,"cause_22");
954 //NOTE: callpbx must be set here
955 /* add relation to existing call */
956 if (!(relation=callpbx->add_relation()))
960 relation->type = RELATION_TYPE_SETUP;
961 relation->channel_state = CHANNEL_STATE_CONNECT;
962 relation->rx_state = NOTIFY_STATE_ACTIVE;
963 relation->tx_state = NOTIFY_STATE_ACTIVE;
964 relation->epoint_id = ea_endpoint->ep_serial;
967 ea_endpoint->ep_call_id = call->c_serial;
969 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s dialing room: %d\n", ea_endpoint->ep_serial, e_terminal, partyline);
971 set_tone(portlist, "proceeding");
972 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
973 message_put(message);
975 new_state(EPOINT_STATE_IN_PROCEEDING);
977 /* send setup to call */
978 printlog("%3d action PARTYLINE call to room %d.\n", ea_endpoint->ep_serial, partyline);
979 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_SETUP);
980 message->param.setup.partyline = partyline;
981 memcpy(&message->param.setup.dialinginfo, &e_dialinginfo, sizeof(struct dialing_info));
982 memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
983 memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
984 memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
985 message_put(message);
990 * process hangup of all calls
992 void EndpointAppPBX::action_hangup_call(void)
996 printlog("%3d action CALL to '%s' hangs up.\n", ea_endpoint->ep_serial, e_dialinginfo.number);
998 if (e_terminal[0] == '\0')
1000 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s: cannot store last dialed number '%s' because caller is unknown (not internal).\n", ea_endpoint->ep_serial, e_terminal, e_dialinginfo.number);
1003 if (!(read_extension(&e_ext, e_terminal)))
1005 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s: cannot store last dialed number '%s' because cannot read settings.\n", ea_endpoint->ep_serial, e_terminal, e_dialinginfo.number);
1008 if (e_dialinginfo.number[0] == '\0')
1010 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s: cannot store last dialed number because nothing was dialed.\n", ea_endpoint->ep_serial, e_terminal);
1013 if (!strcmp(e_dialinginfo.number, e_ext.last_out[0]))
1015 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s: cannot store last dialed number '%s' because it is identical with the last one.\n", ea_endpoint->ep_serial, e_terminal, e_dialinginfo.number);
1020 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s: storing last number '%s'.\n", ea_endpoint->ep_serial, e_terminal, e_dialinginfo.number);
1024 UCPY(e_ext.last_out[i], e_ext.last_out[i-1]);
1027 SCPY(e_ext.last_out[0], e_dialinginfo.number);
1029 /* write extension */
1030 write_extension(&e_ext, e_terminal);
1035 * process dialing 'login'
1037 void EndpointAppPBX::action_dialing_login(void)
1039 struct port_list *portlist = ea_endpoint->ep_portlist;
1040 struct message *message;
1042 struct route_param *rparam;
1044 /* extension parameter */
1045 if ((rparam = routeparam(e_action, PARAM_EXTENSION)))
1047 /* extension is given by parameter */
1048 extension = rparam->string_value;
1049 if (extension[0] == '\0')
1051 if (!read_extension(&e_ext, extension))
1053 printlog("%3d action LOGIN given extension %s doesn't exist.\n", ea_endpoint->ep_serial, extension);
1054 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): given extension %s not found.\n", ea_endpoint->ep_serial, extension);
1055 /* extension doesn't exist */
1056 new_state(EPOINT_STATE_OUT_DISCONNECT);
1057 message_disconnect_port(portlist, CAUSE_UNALLOCATED, LOCATION_PRIVATE_LOCAL, "");
1058 set_tone(portlist, "cause_86");
1063 /* extension must be given by dialstring */
1064 extension = e_extdialing;
1065 if (extension[0] == '\0')
1067 if (!read_extension(&e_ext, extension))
1069 printlog("%3d action LOGIN given extension %s incomplete or not found..\n", ea_endpoint->ep_serial, extension);
1070 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): extension %s incomplete or not found\n", ea_endpoint->ep_serial, extension);
1075 /* we changed our extension */
1076 SCPY(e_terminal, extension);
1077 new_state(EPOINT_STATE_CONNECT);
1079 e_connectedmode = 1;
1081 /* send connect with extension's caller id (COLP) */
1082 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
1083 SCPY(message->param.connectinfo.id, e_ext.callerid);
1084 message->param.connectinfo.ntype = e_ext.callerid_type;
1085 if (e_ext.callerid_present==INFO_PRESENT_ALLOWED && e_callerinfo.present==INFO_PRESENT_RESTRICTED)
1086 message->param.connectinfo.present = INFO_PRESENT_RESTRICTED;
1087 else message->param.connectinfo.present = e_ext.callerid_present;
1088 /* handle restricted caller ids */
1089 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);
1090 /* display callerid if desired for extension */
1091 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));
1092 message->param.connectinfo.ntype = e_ext.callerid_type;
1093 message_put(message);
1094 logmessage(message);
1096 /* set our caller id */
1097 SCPY(e_callerinfo.id, e_ext.callerid);
1098 e_callerinfo.ntype = e_ext.callerid_type;
1099 e_callerinfo.present = e_ext.callerid_present;
1101 /* enable connectedmode */
1102 e_connectedmode = 1;
1105 if (!(rparam = routeparam(e_action, PARAM_NOPASSWORD)))
1107 /* make call state to enter password */
1108 printlog("%3d action LOGIN to extension %s, ask for password.\n", ea_endpoint->ep_serial, e_terminal);
1109 new_state(EPOINT_STATE_IN_OVERLAP);
1112 e_action = &action_password;
1113 e_match_timeout = 0;
1114 e_match_to_action = NULL;
1115 e_dialinginfo.number[0] = '\0';
1116 e_extdialing = strchr(e_dialinginfo.number, '\0');
1119 e_password_timeout = now+20;
1125 /* make call state */
1126 new_state(EPOINT_STATE_IN_OVERLAP);
1127 e_ruleset = ruleset_main;
1129 e_rule = e_ruleset->rule_first;
1131 e_dialinginfo.number[0] = '\0';
1132 e_extdialing = e_dialinginfo.number;
1133 set_tone(portlist, "dialpbx");
1139 * process init 'change_callerid'
1141 void EndpointAppPBX::action_init_change_callerid(void)
1143 struct port_list *portlist = ea_endpoint->ep_portlist;
1145 if (!e_ext.change_callerid)
1147 /* service not available */
1148 printlog("%3d action CHANGE-CALLERID denied for this caller.\n", ea_endpoint->ep_serial);
1149 message_disconnect_port(portlist, CAUSE_SERVICEUNAVAIL, LOCATION_PRIVATE_LOCAL, "");
1150 new_state(EPOINT_STATE_OUT_DISCONNECT);
1151 set_tone(portlist,"cause_87");
1156 /* process dialing callerid
1158 void EndpointAppPBX::_action_callerid_calleridnext(int next)
1160 struct port_list *portlist = ea_endpoint->ep_portlist;
1161 struct route_param *rparam;
1162 char buffer[64], *callerid;
1164 if ((rparam = routeparam(e_action, PARAM_CALLERID)))
1166 /* the caller ID is given by parameter */
1167 callerid = rparam->string_value;
1170 /* caller ID is dialed */
1171 if (!strchr(e_extdialing, '#'))
1173 /* no complete ID yet */
1176 *strchr(e_extdialing, '#') = '\0';
1177 callerid = e_extdialing;
1180 /* given callerid type */
1181 if ((rparam = routeparam(e_action, PARAM_CALLERIDTYPE)))
1182 switch(rparam->integer_value)
1184 case INFO_NTYPE_SUBSCRIBER:
1185 SPRINT(buffer, "s%s", callerid);
1188 case INFO_NTYPE_NATIONAL:
1189 SPRINT(buffer, "n%s", callerid);
1192 case INFO_NTYPE_INTERNATIONAL:
1193 SPRINT(buffer, "i%s", callerid);
1197 SPRINT(buffer, "%s", callerid);
1202 /* caller id complete, dialing with new caller id */
1203 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s: storing callerid '%s' for all following calls.\n", ea_endpoint->ep_serial, e_terminal, callerid);
1204 /* write new parameters */
1205 if (read_extension(&e_ext, e_terminal))
1207 if (callerid[0] == '\0')
1210 (!next)?e_ext.callerid_present:e_ext.id_next_call_present = INFO_PRESENT_RESTRICTED;
1214 (!next)?e_ext.callerid_present:e_ext.id_next_call_present = INFO_PRESENT_ALLOWED;
1215 if ((rparam = routeparam(e_action, PARAM_PRESENT))) if (rparam->integer_value == 0)
1216 (!next)?e_ext.callerid_present:e_ext.id_next_call_present = INFO_PRESENT_RESTRICTED;
1217 if (e_ext.callerid_type == INFO_NTYPE_UNKNOWN) /* if callerid is unknown, the given id is not nationalized */
1219 SCPY((!next)?e_ext.callerid:e_ext.id_next_call, callerid);
1220 (!next)?e_ext.callerid_type:e_ext.id_next_call_type = INFO_NTYPE_UNKNOWN;
1223 SCPY((!next)?e_ext.callerid:e_ext.id_next_call, nationalize_callerinfo(callerid,&((!next)?e_ext.callerid_type:e_ext.id_next_call_type)));
1225 if (!next) e_ext.id_next_call_type = -1;
1226 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): nationalized callerid: '%s' type=%d\n", ea_endpoint->ep_serial, (!next)?e_ext.callerid:e_ext.id_next_call, (!next)?e_ext.callerid_type:e_ext.id_next_call_type);
1228 write_extension(&e_ext, e_terminal);
1231 /* function activated */
1232 printlog("%3d action CHANGE-CALLERID caller changes caller id%s to '%s'.\n", ea_endpoint->ep_serial, next?" of next call":"", callerid);
1233 message_disconnect_port(portlist, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, "");
1234 new_state(EPOINT_STATE_OUT_DISCONNECT);
1235 set_tone(portlist,"activated");
1238 /* process dialing callerid for all call
1240 void EndpointAppPBX::action_dialing_callerid(void)
1242 _action_callerid_calleridnext(0);
1245 /* process dialing callerid for next call
1247 void EndpointAppPBX::action_dialing_calleridnext(void)
1249 _action_callerid_calleridnext(1);
1254 * process init 'change_forward'
1256 void EndpointAppPBX::action_init_change_forward(void)
1258 struct port_list *portlist = ea_endpoint->ep_portlist;
1260 if (!e_ext.change_forward)
1262 printlog("%3d action CHANGE-FORWARD denied for this caller.\n", ea_endpoint->ep_serial);
1263 /* service not available */
1264 message_disconnect_port(portlist, CAUSE_SERVICEUNAVAIL, LOCATION_PRIVATE_LOCAL, "");
1265 new_state(EPOINT_STATE_OUT_DISCONNECT);
1266 set_tone(portlist,"cause_87");
1271 /* process dialing forwarding
1273 void EndpointAppPBX::action_dialing_forward(void)
1275 struct port_list *portlist = ea_endpoint->ep_portlist;
1276 int diversion = INFO_DIVERSION_CFU;
1277 char *dest = e_extdialing;
1278 struct route_param *rparam;
1280 /* if diversion type is given */
1281 if ((rparam = routeparam(e_action, PARAM_DIVERSION)))
1282 diversion = rparam->integer_value;
1284 if ((rparam = routeparam(e_action, PARAM_DEST)))
1286 /* if destination is given */
1287 dest = rparam->string_value;
1290 if (!strchr(e_extdialing, '#'))
1292 *strchr(e_extdialing, '#') = '\0';
1293 dest = e_extdialing;
1296 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s: storing forwarding to '%s'.\n", ea_endpoint->ep_serial, e_terminal, dest);
1297 if (read_extension(&e_ext, e_terminal))
1301 case INFO_DIVERSION_CFU:
1302 printlog("%3d action CHANGE-FORWARD changing CFU (unconditional) to '%s'.\n", ea_endpoint->ep_serial, dest);
1303 SCPY(e_ext.cfu, dest);
1305 case INFO_DIVERSION_CFB:
1306 printlog("%3d action CHANGE-FORWARD changing CFB (busy) to '%s'.\n", ea_endpoint->ep_serial, dest);
1307 SCPY(e_ext.cfb, dest);
1309 case INFO_DIVERSION_CFNR:
1310 if ((rparam = routeparam(e_action, PARAM_DELAY)))
1311 e_ext.cfnr_delay = rparam->integer_value;
1312 printlog("%3d action CHANGE-FORWARD changing CFNR (no response) to '%s' with delay=%d.\n", ea_endpoint->ep_serial, dest, e_ext.cfnr_delay);
1313 SCPY(e_ext.cfnr, dest);
1315 case INFO_DIVERSION_CFP:
1316 printlog("%3d action CHANGE-FORWARD changing CFP (parallel) to '%s'.\n", ea_endpoint->ep_serial, dest);
1317 SCPY(e_ext.cfp, dest);
1320 write_extension(&e_ext, e_terminal);
1322 /* function (de)activated */
1323 message_disconnect_port(portlist, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, "");
1324 new_state(EPOINT_STATE_OUT_DISCONNECT);
1326 set_tone(portlist,"activated");
1328 set_tone(portlist,"deactivated");
1332 /* process dialing redial
1334 void EndpointAppPBX::action_init_redial_reply(void)
1336 struct port_list *portlist = ea_endpoint->ep_portlist;
1339 if (!e_ext.last_out[0])
1341 printlog("%3d action REDIAL/REPLY no number available to dial.\n", ea_endpoint->ep_serial);
1342 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): no stored last number.\n", ea_endpoint->ep_serial);
1343 new_state(EPOINT_STATE_OUT_DISCONNECT);
1344 message_disconnect_port(portlist, CAUSE_SERVICEUNAVAIL, LOCATION_PRIVATE_LOCAL, "");
1345 set_tone(portlist, "cause_3f");
1350 /* process dialing redial
1352 void EndpointAppPBX::_action_redial_reply(int in)
1354 struct message *message;
1356 struct route_param *rparam;
1358 last = (in)?e_ext.last_in[0]:e_ext.last_out[0];
1360 /* if no display is available */
1361 if (!e_ext.display_menu)
1363 if (ea_endpoint->ep_portlist->port_type!=PORT_TYPE_DSS1_NT_IN && ea_endpoint->ep_portlist->port_type!=PORT_TYPE_DSS1_NT_OUT)
1366 /* if select is not given */
1367 if (!(rparam = routeparam(e_action, PARAM_SELECT)))
1371 if (e_extdialing[0]=='*' || e_extdialing[0]=='1')
1373 /* find prev entry */
1379 if (e_extdialing[0]=='#' || e_extdialing[0]=='3')
1381 /* find next entry */
1383 if (e_select >= MAX_REMEMBER)
1386 if (e_ext.last_in[e_select][0] == '\0')
1389 if (e_ext.last_out[e_select][0] == '\0')
1394 last = (in)?e_ext.last_in[e_select]:e_ext.last_out[e_select];
1395 if (e_extdialing[0]=='0' || e_extdialing[0]=='2')
1398 printlog("%3d action REDIAL/REPLY dialing '%s'.\n", ea_endpoint->ep_serial, last);
1399 SCPY(e_dialinginfo.number, last);
1400 e_extdialing = e_dialinginfo.number;
1405 e_extdialing[0] = '\0';
1407 /* send display message to port */
1408 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1409 if (!strncmp(last, "extern:", 7))
1410 SPRINT(message->param.notifyinfo.display, "(%d) %s ext", e_select+1, last+7);
1412 if (!strncmp(last, "intern:", 7))
1413 SPRINT(message->param.notifyinfo.display, "(%d) %s int", e_select+1, last+7);
1415 if (!strncmp(last, "h323:", 5))
1416 SPRINT(message->param.notifyinfo.display, "(%d) %s h323", e_select+1, last+5);
1418 if (!strncmp(last, "chan:", 4))
1419 SPRINT(message->param.notifyinfo.display, "(%d) %s chan", e_select+1, last+5);
1421 if (!strncmp(last, "vbox:", 5))
1422 SPRINT(message->param.notifyinfo.display, "(%d) %s vbox", e_select+1, last+5);
1424 SPRINT(message->param.notifyinfo.display, "(%d) %s", e_select+1, (last[0])?last:"- empty -");
1425 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s sending display:%s\n", ea_endpoint->ep_serial, e_terminal, message->param.notifyinfo.display);
1426 message_put(message);
1427 logmessage(message);
1430 /* process dialing redial
1432 void EndpointAppPBX::action_dialing_redial(void)
1434 _action_redial_reply(0);
1437 /* process dialing reply
1439 void EndpointAppPBX::action_dialing_reply(void)
1441 _action_redial_reply(1);
1445 /* dialing powerdialing delay
1447 void EndpointAppPBX::action_dialing_powerdial(void)
1449 struct port_list *portlist = ea_endpoint->ep_portlist;
1450 struct message *message;
1451 struct route_param *rparam;
1453 /* power dialing only possible if we have a last dialed number */
1454 if (!e_ext.last_out[0])
1456 printlog("%3d action POWERDIAL no number available to redial.\n", ea_endpoint->ep_serial);
1457 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): no stored last number.\n", ea_endpoint->ep_serial);
1458 new_state(EPOINT_STATE_OUT_DISCONNECT);
1459 message_disconnect_port(portlist, CAUSE_SERVICEUNAVAIL, LOCATION_PRIVATE_LOCAL, "");
1460 set_tone(portlist, "cause_3f");
1465 if ((rparam = routeparam(e_action, PARAM_LIMIT)))
1467 e_powerlimit = rparam->integer_value;
1474 if ((rparam = routeparam(e_action, PARAM_DELAY)))
1476 e_powerdelay = rparam->integer_value;
1479 /* delay incomplete */
1480 if (!strchr(e_extdialing, '#'))
1482 *strchr(e_extdialing, '#') = '\0';
1483 e_powerdelay = e_extdialing[0]?atoi(e_extdialing): 0;
1486 if (e_powerdelay < 1)
1488 printlog("%3d action POWERDIAL to '%s' with delay=%d.\n", ea_endpoint->ep_serial, e_ext.last_out[0], (int)e_powerdelay);
1489 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): powerdialing to '%s' (delay=%d).\n", ea_endpoint->ep_serial, e_ext.last_out[0], (int)e_powerdelay);
1491 /* send connect to avoid overlap timeout */
1492 // new_state(EPOINT_STATE_CONNECT); connect may prevent further dialing
1495 memset(&e_connectinfo, 0, sizeof(e_connectinfo));
1496 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
1497 message_put(message);
1498 logmessage(message);
1501 SCPY(e_dialinginfo.number, e_ext.last_out[0]);
1502 e_powerdialing = -1; /* indicates the existence of powerdialing but no redial time given */
1511 void EndpointAppPBX::action_dialing_callback(void)
1513 struct port_list *portlist = ea_endpoint->ep_portlist;
1514 struct route_param *rparam;
1515 struct extension cbext;
1517 portlist = ea_endpoint->ep_portlist;
1519 /* check given extension */
1520 if (!(rparam = routeparam(e_action, PARAM_EXTENSION)))
1522 printlog("%3d action CALLBACK no extension was specified in routing.conf.\n", ea_endpoint->ep_serial);
1523 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): rejecting callback, because no extension was specified in routing.conf\n", ea_endpoint->ep_serial);
1526 new_state(EPOINT_STATE_OUT_DISCONNECT);
1527 message_disconnect_port(portlist, CAUSE_SERVICEUNAVAIL, LOCATION_PRIVATE_LOCAL, "");
1528 set_tone(portlist, "cause_3f");
1530 e_cbcaller[0] = e_cbdialing[0] = '\0';
1534 /* if extension is given */
1535 SCPY(e_cbcaller, rparam->string_value);
1536 if (e_cbcaller[0] == '\0')
1538 printlog("%3d action CALLBACK extension specified in routing.conf is an empty string.\n", ea_endpoint->ep_serial);
1539 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): rejecting callback, because given extension is an empty string.\n", ea_endpoint->ep_serial);
1543 /* read callback extension */
1544 memset(&cbext, 0, sizeof(cbext));
1545 if (!read_extension(&cbext, e_cbcaller))
1547 printlog("%3d action CALLBACK extension '%s' specified in routing.conf doesn't exist.\n", ea_endpoint->ep_serial, e_cbcaller);
1548 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): rejecting callback, because given extension does not exist.\n", ea_endpoint->ep_serial);
1552 /* if password is not given */
1553 if (cbext.password[0] == '\0')
1555 printlog("%3d action CALLBACK extension '%s' has no password specified.\n", ea_endpoint->ep_serial, e_cbcaller);
1556 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): rejecting callback, because no password is available in given extension (%s).\n", ea_endpoint->ep_serial, e_cbcaller);
1560 /* callback only possible if callerid exists OR it is given */
1561 if ((rparam = routeparam(e_action, PARAM_CALLTO)))
1562 SCPY(e_cbto, rparam->string_value);
1565 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): callback to given number: '%s'\n", ea_endpoint->ep_serial, e_cbto);
1566 printlog("%3d action CALLBACK callback to given number: '%s'\n", ea_endpoint->ep_serial, e_cbto);
1567 SCPY(e_callerinfo.id, e_cbto);
1568 e_callerinfo.ntype = INFO_NTYPE_UNKNOWN;
1569 e_callerinfo.present = INFO_PRESENT_ALLOWED;
1571 if (e_callerinfo.id[0]=='\0' || e_callerinfo.present==INFO_PRESENT_NOTAVAIL)
1573 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): rejecting callback, because no caller id is available\n", ea_endpoint->ep_serial);
1574 printlog("%3d action CALLBACK not possible because caller ID is not available.\n", ea_endpoint->ep_serial);
1578 e_callerinfo.present = INFO_PRESENT_ALLOWED;
1583 * process hangup 'callback'
1585 void EndpointAppPBX::action_hangup_callback(void)
1587 struct route_param *rparam;
1591 delay = 2; /* default value */
1592 if ((rparam = routeparam(e_action, PARAM_DELAY)))
1593 if (rparam->integer_value>0)
1594 delay = rparam->integer_value;
1596 /* dialing after callback */
1597 if ((rparam = routeparam(e_action, PARAM_PREFIX)))
1598 SCPY(e_cbdialing, rparam->string_value);
1600 SCPY(e_cbdialing, e_extdialing);
1602 printlog("%3d action CALLBACK extension=%s callerid='%s' delay='%d' dialing after callback='%s' .\n", ea_endpoint->ep_serial, e_cbcaller, e_callerinfo.id, delay, e_cbdialing);
1603 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): caller '%s', callerid '%s', dialing '%s', delay %d\n", ea_endpoint->ep_serial, e_cbcaller, e_callerinfo.id, e_cbdialing, delay);
1605 /* set time to callback */
1606 e_callback = now_d + delay;
1611 * dialing action abbreviation
1613 void EndpointAppPBX::action_dialing_abbrev(void)
1615 struct port_list *portlist = ea_endpoint->ep_portlist;
1616 char *abbrev, *phone, *name;
1619 portlist = ea_endpoint->ep_portlist;
1621 /* abbrev dialing is only possible if we have a caller defined */
1624 printlog("%3d action ABBREVIATION only possible for internal callers.\n", ea_endpoint->ep_serial);
1625 new_state(EPOINT_STATE_OUT_DISCONNECT);
1626 message_disconnect_port(portlist, CAUSE_SERVICEUNAVAIL, LOCATION_PRIVATE_LOCAL, "");
1627 set_tone(portlist, "cause_3f");
1631 /* check abbreviation */
1632 abbrev = e_extdialing;
1635 result = parse_phonebook(e_terminal, &abbrev, &phone, &name);
1638 printlog("%3d action ABBREVIATION '%s' not found.\n", ea_endpoint->ep_serial, abbrev);
1639 new_state(EPOINT_STATE_OUT_DISCONNECT);
1640 message_disconnect_port(portlist, CAUSE_UNALLOCATED, LOCATION_PRIVATE_LOCAL, "");
1641 set_tone(portlist, "cause_01");
1644 if (result == -1) /* may match if more digits are dialed */
1649 /* dial abbreviation */
1650 printlog("%3d action ABBREVIATION mapping '%s' to '%s' (%s), dialing...\n", ea_endpoint->ep_serial, abbrev, phone, name?name:"unknown");
1651 SCPY(e_dialinginfo.number, phone);
1652 e_extdialing = e_dialinginfo.number;
1658 /* process dialing 'test'
1660 void EndpointAppPBX::action_dialing_test(void)
1664 struct port_list *portlist = ea_endpoint->ep_portlist;
1665 struct message *message;
1667 char testcode[32] = "";
1668 struct route_param *rparam;
1670 /* given testcode */
1671 if ((rparam = routeparam(e_action, PARAM_PREFIX)))
1672 SCPY(testcode, rparam->string_value);
1673 SCAT(testcode, e_extdialing);
1678 printlog("%3d action TESTMODE executing 'proceeding' test.\n", ea_endpoint->ep_serial);
1679 new_state(EPOINT_STATE_IN_PROCEEDING);
1680 set_tone(portlist, "proceeding");
1681 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
1682 message_put(message);
1683 logmessage(message);
1687 printlog("%3d action TESTMODE executing 'alerting' test.\n", ea_endpoint->ep_serial);
1688 new_state(EPOINT_STATE_IN_ALERTING);
1689 set_tone(portlist, "ringpbx");
1690 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_ALERTING);
1691 message_put(message);
1692 logmessage(message);
1696 printlog("%3d action TESTMODE executing 'echo connect' test.\n", ea_endpoint->ep_serial);
1697 new_state(EPOINT_STATE_CONNECT);
1700 set_tone(portlist, NULL);
1701 memset(&e_connectinfo, 0, sizeof(e_connectinfo));
1702 SCPY(e_connectinfo.id, e_callerinfo.id);
1703 SCPY(e_connectinfo.intern, e_callerinfo.intern);
1704 SCPY(e_connectinfo.voip, e_callerinfo.voip);
1705 e_connectinfo.itype = e_callerinfo.itype;
1706 e_connectinfo.ntype = e_callerinfo.ntype;
1707 e_connectinfo.present = e_callerinfo.present;
1708 e_connectinfo.screen = e_callerinfo.screen;
1709 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
1710 memcpy(&message->param.connectinfo, &e_connectinfo, sizeof(struct connect_info));
1711 /* handle restricted caller ids */
1712 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);
1713 /* display callerid if desired for extension */
1714 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));
1715 message_put(message);
1716 logmessage(message);
1718 port = find_port_id(portlist->port_id);
1721 port->set_echotest(1);
1726 printlog("%3d action TESTMODE executing 'tone connect' test.\n", ea_endpoint->ep_serial);
1727 new_state(EPOINT_STATE_CONNECT);
1730 memset(&e_connectinfo, 0, sizeof(e_connectinfo));
1731 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
1732 message_put(message);
1733 logmessage(message);
1734 set_tone(portlist, "test");
1738 printlog("%3d action TESTMODE executing 'hold music' test.\n", ea_endpoint->ep_serial);
1739 new_state(EPOINT_STATE_CONNECT);
1742 memset(&e_connectinfo, 0, sizeof(e_connectinfo));
1743 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
1744 message_put(message);
1745 logmessage(message);
1746 set_tone(portlist, "hold");
1750 if (strlen(testcode) < 4)
1753 cause = atoi(testcode+1);
1756 printlog("%3d action TESTMODE executing 'announcement' test with cause %d.\n", ea_endpoint->ep_serial, cause);
1757 new_state(EPOINT_STATE_CONNECT);
1760 SPRINT(causestr,"cause_%02x",cause);
1761 memset(&e_connectinfo, 0, sizeof(e_connectinfo));
1762 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
1763 message_put(message);
1764 logmessage(message);
1765 set_tone(portlist, causestr);
1769 if (strlen(testcode) < 4)
1772 cause = atoi(testcode+1);
1775 printlog("%3d action TESTMODE executing 'disconnect' test with cause %d.\n", ea_endpoint->ep_serial, cause);
1776 new_state(EPOINT_STATE_OUT_DISCONNECT);
1777 SPRINT(causestr,"cause_%02x",cause);
1778 message_disconnect_port(portlist, cause, LOCATION_PRIVATE_LOCAL, "");
1779 set_tone(portlist, causestr);
1782 case '8': /* release */
1783 printlog("%3d action TESTMODE executing 'release' test.\n", ea_endpoint->ep_serial);
1784 new_state(EPOINT_STATE_OUT_DISCONNECT);
1785 message_disconnect_port(portlist, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, "");
1786 set_tone(portlist, "release");
1789 case '9': /* text callerid test */
1790 printlog("%3d action TESTMODE executing 'caller id' test.\n", ea_endpoint->ep_serial);
1791 new_state(EPOINT_STATE_CONNECT);
1794 memset(&e_connectinfo, 0, sizeof(e_connectinfo));
1795 SCPY(e_connectinfo.id, "12345678");
1796 SCPY(e_connectinfo.name, "Welcome to Linux");
1797 SCPY(e_connectinfo.display, "Welcome to Linux");
1798 e_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
1799 e_connectinfo.present = INFO_PRESENT_ALLOWED;
1800 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
1801 memcpy(&message->param.connectinfo, &e_connectinfo, sizeof(message->param.connectinfo));
1802 message_put(message);
1803 logmessage(message);
1804 set_tone(portlist, "hold");
1810 /* process init play
1812 void EndpointAppPBX::action_init_play(void)
1814 struct route_param *rparam;
1815 struct port_list *portlist = ea_endpoint->ep_portlist;
1817 /* check given sample */
1818 if (!(rparam = routeparam(e_action, PARAM_SAMPLE)))
1820 printlog("%3d action PLAY no sample given.\n", ea_endpoint->ep_serial);
1821 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): cannot play, because no sample has been specified\n", ea_endpoint->ep_serial);
1824 new_state(EPOINT_STATE_OUT_DISCONNECT);
1825 message_disconnect_port(portlist, CAUSE_UNSPECIFIED, LOCATION_PRIVATE_LOCAL, "");
1826 set_tone(portlist, "cause_3f");
1831 /* if sample is given */
1832 if (rparam->string_value[0] == '\0')
1834 printlog("%3d action PLAY sample name with empty string given.\n", ea_endpoint->ep_serial);
1835 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): cannot play, because given sample is an empty string.\n", ea_endpoint->ep_serial);
1842 set_tone(ea_endpoint->ep_portlist, rparam->string_value);
1847 * action_*_vbox_play is implemented in "action_vbox.cpp"
1852 * process dialing of calculator
1854 void EndpointAppPBX::action_dialing_calculator(void)
1856 struct port_list *portlist = ea_endpoint->ep_portlist;
1857 struct message *message;
1858 double value1, value2, v, sign1;
1859 int komma1, komma2, k, state, mode, first;
1862 portlist = ea_endpoint->ep_portlist;
1864 /* remove error message */
1865 if (!strncmp(e_extdialing, "Error", 5))
1867 UCPY(e_extdialing, e_extdialing+5);
1869 if (!strncmp(e_extdialing, "inf", 3))
1871 UCPY(e_extdialing, e_extdialing+3);
1873 if (!strncmp(e_extdialing, "-inf", 4))
1875 UCPY(e_extdialing, e_extdialing+4);
1878 /* process dialing */
1891 if (*p>='0' && *p<='9')
1899 if ((p[-1]<'0' || p[-1]>'0') && p[-1]!='.')
1908 case 0: /* first number */
1911 value1 = value1*10 + (*p-'0');
1921 case 1: /* second number */
1924 value2 = value2*10 + (*p-'0');
1941 UCPY(e_extdialing, "Error");
1944 /* if there is a multiplication, we change to / */
1953 /* if there is a division, we change to + */
1962 /* if there is a addition, we change to - */
1971 /* if there is a substraction and a comma, we change to * */
1972 if (p[-1]=='-' && komma1)
1980 /* if there is a substraction and no comma and the first or second value, we change to , */
1989 /* if there is a komma and we are at the first value, we change to * */
1990 if (p[-1]=='.' && state==0)
1999 /* if there is a komma and we are at the second value, we display error */
2000 if (komma2 && state==1)
2002 UCPY(e_extdialing, "Error");
2005 /* if we are at state 1, we write a comma */
2012 /* we assume multiplication */
2019 /* if just a number is displayed, the input is cleared */
2022 *e_extdialing = '\0';
2025 /* calculate the result */
2028 case 0: /* multiply */
2029 UNPRINT(e_extdialing, sizeof(e_dialinginfo.number)-strlen(e_dialinginfo.number), "%.8f", sign1*value1*value2);
2031 case 1: /* divide */
2032 UNPRINT(e_extdialing, sizeof(e_dialinginfo.number)-strlen(e_dialinginfo.number), "%.8f", sign1*value1/value2);
2035 UNPRINT(e_extdialing, sizeof(e_dialinginfo.number)-strlen(e_dialinginfo.number), "%.8f", sign1*value1+value2);
2037 case 3: /* substract */
2038 UNPRINT(e_extdialing, sizeof(e_dialinginfo.number)-strlen(e_dialinginfo.number), "%.8f", sign1*value1-value2);
2041 e_dialinginfo.number[sizeof(e_dialinginfo.number)-1] = '\0';
2042 if (strchr(e_extdialing, '.')) /* remove zeroes */
2044 while (e_extdialing[strlen(e_extdialing)-1] == '0')
2045 e_extdialing[strlen(e_extdialing)-1] = '\0';
2046 if (e_extdialing[strlen(e_extdialing)-1] == '.')
2047 e_extdialing[strlen(e_extdialing)-1] = '\0'; /* and remove dot */
2049 p = strchr(e_extdialing,'\0')-1;
2082 UCPY(e_extdialing, "Error");
2091 /* display dialing */
2092 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
2093 SPRINT(message->param.notifyinfo.display, ">%s", e_extdialing);
2094 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s displaying interpreted dialing '%s' internal values: %f %f\n", ea_endpoint->ep_serial, e_terminal, e_extdialing, value1, value2);
2095 message_put(message);
2096 logmessage(message);
2101 * process dialing of timer
2103 void EndpointAppPBX::action_dialing_timer(void)
2109 * process 'goto' or 'menu'
2111 void EndpointAppPBX::_action_goto_menu(int mode)
2113 struct port_list *portlist = ea_endpoint->ep_portlist;
2114 struct route_param *rparam;
2116 /* check given ruleset */
2117 if (!(rparam = routeparam(e_action, PARAM_RULESET)))
2120 printlog("%3d action GOTO/MENU no ruleset ginven in options.conf\n", ea_endpoint->ep_serial);
2121 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): no ruleset was secified for action '%s' in routing.conf\n", ea_endpoint->ep_serial, (mode)?"menu":"goto");
2124 new_state(EPOINT_STATE_OUT_DISCONNECT);
2125 message_disconnect_port(portlist, CAUSE_SERVICEUNAVAIL, LOCATION_PRIVATE_LOCAL, "");
2126 set_tone(portlist, "cause_3f");
2130 if (rparam->string_value[0] == '\0')
2132 e_ruleset = getrulesetbyname(rparam->string_value);
2135 printlog("%3d action GOTO/MENU given ruleset '%s' not found in options.conf\n", ea_endpoint->ep_serial, rparam->string_value);
2136 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): given ruleset '%s' for action '%s' was not found in routing.conf\n", ea_endpoint->ep_serial, rparam->string_value, (mode)?"menu":"goto");
2139 printlog("%3d action GOTO/MENU changing to ruleset '%s'\n", ea_endpoint->ep_serial, rparam->string_value);
2141 /* if the 'menu' was selected, we will flush all digits */
2144 //SCPY(e_dialinginfo.number, e_extdialing);
2145 e_dialinginfo.number[0] = 0;
2146 e_extdialing = e_dialinginfo.number;
2152 if ((rparam = routeparam(e_action, PARAM_SAMPLE)))
2154 printlog("%3d action GOTO/MENU start playing sample '%s'\n", ea_endpoint->ep_serial, rparam->string_value);
2155 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): playing sample '%s'\n", ea_endpoint->ep_serial, rparam->string_value);
2156 set_tone(ea_endpoint->ep_portlist, rparam->string_value);
2159 /* do dialing with new ruleset */
2164 /* process dialing goto
2166 void EndpointAppPBX::action_dialing_goto(void)
2168 _action_goto_menu(0);
2171 /* process dialing menu
2173 void EndpointAppPBX::action_dialing_menu(void)
2175 _action_goto_menu(1);
2180 * process dialing disconnect
2182 void EndpointAppPBX::action_dialing_disconnect(void)
2184 struct route_param *rparam;
2185 struct port_list *portlist = ea_endpoint->ep_portlist;
2186 struct message *message;
2187 int cause = CAUSE_NORMAL; /* normal call clearing */
2188 int location = LOCATION_PRIVATE_LOCAL;
2189 char cause_string[256] = "", display[84] = "";
2191 /* check cause parameter */
2192 if ((rparam = routeparam(e_action, PARAM_CAUSE)))
2194 cause = rparam->integer_value;
2195 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): 'cause' is given: %d\n", ea_endpoint->ep_serial, cause);
2197 if ((rparam = routeparam(e_action, PARAM_LOCATION)))
2199 location = rparam->integer_value;
2200 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): 'location' is given: %d\n", ea_endpoint->ep_serial, location);
2204 /* use cause as sample, if not given later */
2205 SPRINT(cause_string, "cause_%02x", cause);
2207 /* check sample parameter */
2208 if ((rparam = routeparam(e_action, PARAM_SAMPLE)))
2210 SCPY(cause_string, rparam->string_value);
2211 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): 'sample' is given: %s\n", ea_endpoint->ep_serial, cause_string);
2215 if ((rparam = routeparam(e_action, PARAM_DISPLAY)))
2217 SCPY(display, rparam->string_value);
2218 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): 'display' is given: %s\n", ea_endpoint->ep_serial, display);
2221 /* disconnect only if connect parameter is not given */
2222 printlog("%3d action DISCONNECT with cause %d, location %d, sample '%s', display '%s'\n", ea_endpoint->ep_serial, cause, location, cause_string, display);
2223 new_state(EPOINT_STATE_OUT_DISCONNECT);
2224 set_tone(portlist, cause_string);
2225 if (!(rparam = routeparam(e_action, PARAM_CONNECT)))
2227 message_disconnect_port(portlist, cause, location, display);
2230 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
2231 SCPY(message->param.notifyinfo.display, display);
2232 message_put(message);
2233 logmessage(message);
2240 * process dialing help
2242 void EndpointAppPBX::action_dialing_help(void)
2244 /* show all things that would match */
2246 struct numbering *numbering = numbering_int;
2247 char dialing[sizeof(e_dialinginfo.number)];
2249 struct message *message;
2250 struct route_param *rparam;
2252 /* in case we have no menu (this should never happen) */
2257 if (strchr(e_dialinginfo.number,'*'))
2260 e_dialinginfo.number[0] = '\0';
2262 if (strchr(e_dialinginfo.number,'#'))
2265 e_dialinginfo.number[0] = '\0';
2268 /* get position in menu */
2271 /* get last menu position */
2273 while(numbering->next)
2276 numbering = numbering->next;
2280 /* get menu position */
2284 numbering = numbering->next;
2288 numbering = numbering_int;
2295 /* if we dial something else we need to add the prefix and change the action */
2296 if (e_dialinginfo.number[0])
2298 e_action = NUMB_ACTION_NONE;
2299 SCPY(dialing, numbering->prefix);
2300 //we ignore the first digit after selecting
2301 //SCAT(dialing, e_dialinginfo.number);
2302 SCPY(e_dialinginfo.number, dialing);
2303 e_extdialing = e_dialinginfo.number+strlen(numbering->prefix);
2304 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s selected a new menu '%s' dialing: %s\n", ea_endpoint->ep_serial, e_terminal, numb_actions[numbering->action], e_dialinginfo.number);
2310 /* send display message to port */
2311 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
2312 SPRINT(message->param.notifyinfo.display, ">%s %s%s%s", numbering->prefix, numb_actions[numbering->action], (numbering->param[0])?" ":"", numbering->param);
2313 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s selected a new menu '%s' sending display:%s\n", ea_endpoint->ep_serial, e_terminal, numb_actions[numbering->action], message->param.notifyinfo.display);
2314 message_put(message);
2315 logmessage(message);
2321 * process dialing deflect
2323 void EndpointAppPBX::action_dialing_deflect(void)
2329 * process dialing setforward
2331 void EndpointAppPBX::action_dialing_setforward(void)
2337 * process hangup 'execute'
2339 void EndpointAppPBX::action_hangup_execute(void)
2341 struct route_param *rparam;
2342 char *command = "", isdn_port[10];
2343 char *argv[8+1]; /* check also number of args below */
2346 /* get script / command */
2347 if ((rparam = routeparam(e_action, PARAM_EXECUTE)))
2348 command = rparam->string_value;
2349 if (command[0] == '\0')
2351 printlog("%3d action EXECUTE no 'execute' parameter given at routing.conf.\n", ea_endpoint->ep_serial);
2352 PERROR("EPOINT(%d): terminal %s: NO PARAMETER GIVEN for 'execute' action. see routing.conf\n", ea_endpoint->ep_serial, e_terminal);
2355 printlog("%3d action EXECUTE command='%s'\n", ea_endpoint->ep_serial, command);
2356 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s: executing '%s'.\n", ea_endpoint->ep_serial, e_terminal, command);
2359 while(strchr(argv[0], '/'))
2360 argv[0] = strchr(argv[0], '/')+1;
2361 if ((rparam = routeparam(e_action, PARAM_PARAM)))
2363 argv[1] = rparam->string_value;
2366 argv[1+i] = e_extdialing;
2367 argv[2+i] = numberrize_callerinfo(e_callerinfo.id, e_callerinfo.ntype);
2368 argv[3+i] = e_callerinfo.intern;
2369 argv[4+i] = e_callerinfo.voip;
2370 argv[5+i] = e_callerinfo.name;
2371 SPRINT(isdn_port, "%d", e_callerinfo.isdn_port);
2372 argv[6+i] = isdn_port;
2373 argv[7+i] = NULL; /* check also number of args above */
2374 execve("/bin/sh", argv, environ);
2379 * process hangup 'file'
2381 void EndpointAppPBX::action_hangup_file(void)
2383 struct route_param *rparam;
2384 char *file, *content, *mode;
2387 /* get file / content */
2388 if (!(rparam = routeparam(e_action, PARAM_FILE)))
2389 file = rparam->string_value;
2392 if (!(rparam = routeparam(e_action, PARAM_CONTENT)))
2393 content = rparam->string_value;
2395 content = e_extdialing;
2396 if (!(rparam = routeparam(e_action, PARAM_APPEND)))
2400 if (file[0] == '\0')
2402 printlog("%3d action FILE no filename given.\n", ea_endpoint->ep_serial);
2403 PERROR("EPOINT(%d): terminal %s: NO FILENAME GIVEN for 'file' action. see routing.conf\n", ea_endpoint->ep_serial, e_terminal);
2406 if (!(fp = fopen(file, mode)))
2408 printlog("%3d action FILE file '%s' cannot be opened. (errno = %d)\n", ea_endpoint->ep_serial, file, errno);
2409 PERROR("EPOINT(%d): terminal %s: given file '%s' cannot be opened. see routing.conf\n", ea_endpoint->ep_serial, e_terminal, file);
2412 printlog("%3d action FILE file='%s' content='%s'\n", ea_endpoint->ep_serial, file, content);
2413 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s: writing file '%s' with content '%s'.\n", ea_endpoint->ep_serial, e_terminal, file, content);
2414 fprintf(fp, "%s\n", content);
2420 * process init 'pick'
2422 void EndpointAppPBX::action_init_pick(void)
2424 struct route_param *rparam;
2425 char *extensions = NULL;
2427 if ((rparam = routeparam(e_action, PARAM_EXTENSIONS)))
2428 extensions = rparam->string_value;
2430 printlog("%3d action PICK\n", ea_endpoint->ep_serial);
2431 pick_call(extensions);
2436 * process dialing 'password'
2438 void EndpointAppPBX::action_dialing_password(void)
2440 struct port_list *portlist = ea_endpoint->ep_portlist;
2442 /* prompt for password */
2443 if (e_extdialing[0] == '\0')
2445 /* give password tone */
2446 set_tone(portlist, "password");
2448 if (e_extdialing[1] == '\0')
2450 /* give password tone */
2451 set_tone(portlist, "dialing");
2454 /* wait until all digits are dialed */
2455 if (strlen(e_ext.password) != strlen(e_extdialing))
2456 return; /* more digits needed */
2458 /* check the password */
2459 if (e_ext.password[0]=='\0' || (strlen(e_ext.password)==strlen(e_extdialing) && !!strcmp(e_ext.password,e_extdialing)))
2461 printlog("%3d action PASSWORD WRITE password wrong\n", ea_endpoint->ep_serial);
2462 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): password wrong %s\n", ea_endpoint->ep_serial, e_extdialing);
2463 e_connectedmode = 0;
2465 new_state(EPOINT_STATE_OUT_DISCONNECT);
2466 message_disconnect_port(portlist, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, "");
2467 set_tone(portlist, "cause_10");
2471 /* write caller id if ACTION_PASSWORD_WRITE was selected */
2473 if (e_action->index == ACTION_PASSWORD_WRITE)
2475 append_callbackauth(e_terminal, &e_callbackinfo);
2476 printlog("%3d action PASSWORD WRITE password written\n", ea_endpoint->ep_serial);
2479 /* make call state */
2480 new_state(EPOINT_STATE_IN_OVERLAP);
2481 e_ruleset = ruleset_main;
2483 e_rule = e_ruleset->rule_first;
2485 e_dialinginfo.number[0] = '\0';
2486 e_extdialing = e_dialinginfo.number;
2487 set_tone(portlist, "dialpbx");
2490 void EndpointAppPBX::action_dialing_password_wr(void)
2492 action_dialing_password();
2496 /* general process dialing of incoming call
2497 * depending on the detected prefix, subfunctions above (action_*) will be
2500 void EndpointAppPBX::process_dialing(void)
2502 struct port_list *portlist = ea_endpoint->ep_portlist;
2503 struct message *message;
2504 struct route_param *rparam;
2506 //#warning Due to HANG-BUG somewhere here, I added some HANG-BUG-DEBUGGING output that cannot be disabled. after bug has been found, this will be removed.
2507 //PDEBUG(~0, "HANG-BUG-DEBUGGING: entered porcess_dialing\n");
2508 portlist = ea_endpoint->ep_portlist;
2509 /* check if we have a port instance linked to our epoint */
2513 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): note: dialing call requires exactly one port object to process dialing. this case could happen due to a parked call. we end dialing here.\n", ea_endpoint->ep_serial, e_terminal);
2514 e_action_timeout = 0;
2515 e_match_timeout = 0;
2520 goto portlist_error;
2523 /* check nesting levels */
2524 if (++e_rule_nesting > RULE_NESTING)
2526 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): rules are nesting too deep. (%d levels) check for infinite loops in routing.conf\n", ea_endpoint->ep_serial, e_rule_nesting);
2527 new_state(EPOINT_STATE_OUT_DISCONNECT);
2528 message_disconnect_port(portlist, CAUSE_UNSPECIFIED, LOCATION_PRIVATE_LOCAL, "");
2529 set_tone(portlist, "cause_3f");
2530 e_action_timeout = 0;
2531 e_match_timeout = 0;
2535 //PDEBUG(~0, "HANG-BUG-DEBUGGING: before action-timeout processing\n");
2536 /* process timeout */
2537 if (e_action_timeout)
2539 e_action_timeout = 0;
2540 if (e_state == EPOINT_STATE_CONNECT)
2542 PDEBUG(DEBUG_ROUTE|DEBUG_EPOINT, "EPOINT(%d): action timed out, but we already have connected, so we stop timer and continue.\n", ea_endpoint->ep_serial);
2545 if (e_action->index == ACTION_DISCONNECT
2546 || e_state == EPOINT_STATE_OUT_DISCONNECT)
2548 /* release after disconnect */
2549 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
2552 release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, 0);
2553 e_action = e_action->next;
2556 /* nothing more, so we release */
2557 PDEBUG(DEBUG_ROUTE|DEBUG_EPOINT, "EPOINT(%d): action timed out, and we have no next action, so we disconnect.\n", ea_endpoint->ep_serial);
2558 new_state(EPOINT_STATE_OUT_DISCONNECT);
2559 message_disconnect_port(portlist, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, "");
2560 set_tone(portlist, "cause_3f");
2563 PDEBUG(DEBUG_ROUTE|DEBUG_EPOINT, "EPOINT(%d): continueing with action '%s'.\n", ea_endpoint->ep_serial, action_defs[e_action->index].name);
2564 goto action_timeout;
2567 //PDEBUG(~0, "HANG-BUG-DEBUGGING: before setup/overlap state checking\n");
2568 if (e_state!=EPOINT_STATE_IN_SETUP
2569 && e_state!=EPOINT_STATE_IN_OVERLAP)
2571 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): we are not in incomming setup/overlap state, so we ignore init/dialing process.\n", ea_endpoint->ep_serial, e_rule_nesting);
2572 e_match_timeout = 0;
2577 /* check if we do menu selection */
2578 if (e_action==NUMB_ACTION_NONE && (e_dialinginfo.number[0]=='*' || e_dialinginfo.number[0]=='#'))
2579 /* do menu selection */
2580 if (e_ext.display_menu)
2582 if (portlist->port_type==PORT_TYPE_DSS1_NT_IN || portlist->port_type==PORT_TYPE_DSS1_NT_OUT) /* only if the dialing terminal is an isdn telephone connected to an internal port */
2584 e_dialinginfo.number[0] = '\0';
2585 e_action = NUMB_ACTION_MENU;
2588 e_match_timeout = 0;
2591 /* invalid dialing */
2592 message_disconnect_port(portlist, CAUSE_INCALID, LOCATION_PRIVATE_LOCAL, "");
2593 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_DISCONNECT);
2594 message->param.disconnectinfo.cause = CAUSE_INVALID;
2595 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2598 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
2599 SCPY(message->param.notifyinfo.display,get_isdn_cause(LOCATION_PRIVATE_LOCAL, epoint->e_ext.display_cause, param->disconnectinfo.location, param->disconnectinfo.cause));
2601 message_put(message);
2602 logmessage(message);
2604 new_state(EPOINT_STATE_OUT_DISCONNECT);
2605 set_tone(portlist,"cause_1c");
2606 e_match_timeout = 0;
2611 //PDEBUG(~0, "HANG-BUG-DEBUGGING: before e_action==NULL\n");
2612 /* if no action yet, we will call try to find a matching rule */
2615 /* be sure that all selectors are initialized */
2618 /* check for external call */
2619 if (!strncmp(e_dialinginfo.number, "extern:", 7))
2621 e_extdialing = e_dialinginfo.number+7;
2622 e_action = &action_external;
2623 goto process_action;
2625 /* check for internal call */
2626 if (!strncmp(e_dialinginfo.number, "intern:", 7))
2628 e_extdialing = e_dialinginfo.number+7;
2629 e_action = &action_internal;
2630 goto process_action;
2632 /* check for h323 call */
2633 if (!strncmp(e_dialinginfo.number, "h323:", 5))
2635 e_extdialing = e_dialinginfo.number+5;
2636 e_action = &action_h323;
2637 goto process_action;
2639 /* check for chan call */
2640 if (!strncmp(e_dialinginfo.number, "chan:", 5))
2642 e_extdialing = e_dialinginfo.number+4;
2643 e_action = &action_chan;
2644 goto process_action;
2646 /* check for vbox call */
2647 if (!strncmp(e_dialinginfo.number, "vbox:", 5))
2649 e_extdialing = e_dialinginfo.number+5;
2650 e_action = &action_vbox;
2651 goto process_action;
2654 if (e_match_timeout && now_d>=e_match_timeout)
2656 /* return timeout rule */
2657 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal '%s' dialing: '%s', timeout in ruleset '%s'\n", ea_endpoint->ep_serial, e_terminal, e_dialinginfo.number, e_ruleset->name);
2658 e_match_timeout = 0;
2659 e_action = e_match_to_action;
2660 e_extdialing = e_match_to_extdialing;
2661 printlog("%3d routing TIMEOUT processing action '%s' (line %d)\n", ea_endpoint->ep_serial, action_defs[e_action->index].name, e_action->line);
2665 //PDEBUG(~0, "HANG-BUG-DEBUGGING: before routing\n");
2666 /* check for matching rule */
2667 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal '%s' dialing: '%s', checking matching rule of ruleset '%s'\n", ea_endpoint->ep_serial, e_terminal, e_dialinginfo.number, e_ruleset->name);
2670 e_action = route(e_ruleset);
2672 printlog("%3d routing MATCH processing action '%s' (line %d)\n", ea_endpoint->ep_serial, action_defs[e_action->index].name, e_action->line);
2675 e_action = &action_disconnect;
2677 printlog("%3d routing NO MAIN RULESET, DISCONNECTING! '%s'\n", ea_endpoint->ep_serial, action_defs[e_action->index].name);
2679 //PDEBUG(~0, "HANG-BUG-DEBUGGING: after routing\n");
2683 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): no rule within the current ruleset matches yet.\n", ea_endpoint->ep_serial, e_terminal);
2688 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): a rule with action '%s' matches.\n", ea_endpoint->ep_serial, action_defs[e_action->index].name);
2693 e_action_timeout = 0;
2694 if (e_action->timeout)
2696 e_action_timeout = now_d + e_action->timeout;
2697 PDEBUG(DEBUG_ROUTE|DEBUG_EPOINT, "EPOINT(%d): action has a timeout of %d secods.\n", ea_endpoint->ep_serial, e_action->timeout);
2701 /* check param proceeding / alerting / connect */
2702 if ((rparam = routeparam(e_action, PARAM_CONNECT)))
2704 /* NOTE: we may not change our state to connect, because dialing will then not possible */
2706 memset(&e_connectinfo, 0, sizeof(e_connectinfo));
2707 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
2708 message_put(message);
2709 logmessage(message);
2711 if ((rparam = routeparam(e_action, PARAM_ALERTING)))
2713 /* NOTE: we may not change our state to alerting, because dialing will then not possible */
2714 memset(&e_connectinfo, 0, sizeof(e_connectinfo));
2715 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_ALERTING);
2716 message_put(message);
2717 logmessage(message);
2719 if ((rparam = routeparam(e_action, PARAM_PROCEEDING)))
2721 /* NOTE: we may not change our state to proceeding, because dialing will then not possible */
2722 memset(&e_connectinfo, 0, sizeof(e_connectinfo));
2723 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
2724 message_put(message);
2725 logmessage(message);
2728 if (action_defs[e_action->index].init_func)
2730 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s: current action '%s' has a init function, so we call it...\n", ea_endpoint->ep_serial, e_terminal, action_defs[e_action->index].name);
2731 (this->*(action_defs[e_action->index].init_func))();
2733 if (e_state!=EPOINT_STATE_IN_SETUP
2734 && e_state!=EPOINT_STATE_IN_OVERLAP)
2736 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): AFTER init process: we are not in incomming setup/overlap state anymore, so we ignore further dialing process.\n", ea_endpoint->ep_serial, e_rule_nesting);
2737 goto display_action;
2741 /* show what we are doing */
2742 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal '%s' action: %s (dialing '%s')\n", ea_endpoint->ep_serial, e_terminal, action_defs[e_action->index].name, e_extdialing);
2743 /* go to action's dialing function */
2744 if (action_defs[e_action->index].dialing_func)
2746 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s: current action '%s' has a dialing function, so we call it...\n", ea_endpoint->ep_serial, e_terminal, action_defs[e_action->index].name);
2747 (this->*(action_defs[e_action->index].dialing_func))();
2750 /* display selected dialing action if enabled and still in setup state */
2754 if (e_action->index==ACTION_MENU
2755 || e_action->index==ACTION_REDIAL
2756 || e_action->index==ACTION_REPLY
2757 || e_action->index==ACTION_TIMER
2758 || e_action->index==ACTION_CALCULATOR
2759 || e_action->index==ACTION_TEST)
2763 if (!e_ext.display_dialing)
2765 if (e_state==EPOINT_STATE_IN_OVERLAP || e_state==EPOINT_STATE_IN_PROCEEDING || e_state==EPOINT_STATE_IN_ALERTING || e_state==EPOINT_STATE_CONNECT/* || e_state==EPOINT_STATE_IN_DISCONNECT || e_state==EPOINT_STATE_OUT_DISCONNECT*/)
2766 if (portlist->port_type==PORT_TYPE_DSS1_NT_IN || portlist->port_type==PORT_TYPE_DSS1_NT_OUT) /* only if the dialing terminal is an isdn telephone connected to an internal port */
2768 message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
2772 SPRINT(message->param.notifyinfo.display, "> %s", e_dialinginfo.number);
2775 SPRINT(message->param.notifyinfo.display, "%s%s%s", action_defs[e_action->index].name, (e_extdialing[0])?" ":"", e_extdialing);
2778 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s displaying interpreted dialing '%s'\n", ea_endpoint->ep_serial, e_terminal, message->param.notifyinfo.display);
2779 message_put(message);
2780 logmessage(message);
2789 /* some services store information after hangup */
2790 void EndpointAppPBX::process_hangup(int cause, int location)
2792 char callertext[256], dialingtext[256];
2793 int writeext = 0, i;
2795 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal '%s'\n", ea_endpoint->ep_serial, e_terminal);
2798 if (read_extension(&e_ext, e_terminal))
2808 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): writing connect from %s to %s into logfile of %s\n", ea_endpoint->ep_serial, e_callerinfo.id, e_dialinginfo.number, e_terminal);
2809 switch(e_dialinginfo.itype)
2811 case INFO_ITYPE_H323:
2812 SPRINT(dialingtext, "h323:%s", e_dialinginfo.number);
2814 case INFO_ITYPE_CHAN:
2815 SPRINT(dialingtext, "chan:%s", e_dialinginfo.number);
2817 case INFO_ITYPE_INTERN:
2818 SPRINT(dialingtext, "intern:%s", e_dialinginfo.number);
2820 case INFO_ITYPE_VBOX:
2821 SPRINT(dialingtext, "vbox:%s", e_dialinginfo.number);
2824 SPRINT(dialingtext, "%s", e_dialinginfo.number);
2827 if (e_callerinfo.id[0])
2828 SPRINT(callertext, "%s", numberrize_callerinfo(e_callerinfo.id, e_callerinfo.ntype));
2830 SPRINT(callertext, "unknown");
2831 /* allpy restriction */
2832 if (!e_ext.anon_ignore && e_callerinfo.present==INFO_PRESENT_RESTRICTED)
2833 SPRINT(callertext, "anonymous");
2834 if (e_callerinfo.intern[0]) /* add intern if present */
2835 UNPRINT(strchr(callertext,'\0'), sizeof(callertext)-1+strlen(callertext), " (intern %s)", e_callerinfo.intern);
2836 if (e_callerinfo.voip[0]) /* add voip if present */
2837 UNPRINT(strchr(callertext,'\0'), sizeof(callertext)-1+strlen(callertext), " (voip %s)", e_callerinfo.voip);
2838 write_log(e_terminal, callertext, dialingtext, e_start, e_stop, 0, cause, location);
2840 /* store last received call for reply-list */
2841 if (e_callerinfo.id[0] || e_callerinfo.intern[0])
2842 if (e_ext.anon_ignore || e_callerinfo.present!=INFO_PRESENT_RESTRICTED)
2844 if (e_callerinfo.intern[0])
2845 SPRINT(callertext, "intern:%s", e_callerinfo.intern);
2847 SPRINT(callertext, "extern:%s", numberrize_callerinfo(e_callerinfo.id, e_callerinfo.ntype));
2848 if (!!strcmp(callertext, e_ext.last_in[0]))
2853 UCPY(e_ext.last_in[i], e_ext.last_in[i-1]);
2856 SCPY(e_ext.last_in[0], callertext);
2857 writeext |= 1; /* store extension later */
2858 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s: storing last received caller id '%s'.\n", ea_endpoint->ep_serial, e_terminal, e_ext.last_in[0]);
2860 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s: cannot store last received id '%s' because it is identical with the last one.\n", ea_endpoint->ep_serial, e_terminal, callertext);
2864 /* write extension if needed */
2865 if (writeext == 0x11)
2866 write_extension(&e_ext, e_terminal);
2870 if (action_defs[e_action->index].hangup_func)
2872 PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s: current action '%s' has a hangup function, so we call it...\n", ea_endpoint->ep_serial, e_terminal, action_defs[e_action->index].name);
2873 (this->*(action_defs[e_action->index].hangup_func))();