1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
10 \*****************************************************************************/
15 #include <sys/types.h>
22 #include <sys/ioctl.h>
26 #include <sys/resource.h>
34 struct timeval now_tv;
35 struct timezone now_tz;
38 gettimeofday(&now_tv, &now_tz); \
39 now_d = ((double)(now_tv.tv_usec))/1000000 + now_tv.tv_sec; \
40 now = now_tv.tv_sec; \
41 now_tm = localtime(&now); \
43 //#define DEBUG_DURATION
48 pthread_mutex_t mutexd; // debug output mutex
49 pthread_mutex_t mutexl; // log output mutex
50 pthread_mutex_t mutexe; // error output mutex
63 char *debug_prefix = 0;
66 int debug_newline = 1;
69 static void debug(const char *function, int line, char *prefix, char *buffer)
71 /* if we have a new debug count, we add a mark */
72 if (last_debug != debug_count)
74 last_debug = debug_count;
76 printf("\033[34m--------------------- %04d.%02d.%02d %02d:%02d:%02d %06d\033[36m\n", now_tm->tm_year+1900, now_tm->tm_mon+1, now_tm->tm_mday, now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec, debug_count%1000000);
77 if (options.deb&DEBUG_LOG && global_debug)
78 dprint(DBGM_MAN, 0, "--------------------- %04d.%02d.%02d %02d:%02d:%02d %06d\n", now_tm->tm_year+1900, now_tm->tm_mon+1, now_tm->tm_mday, now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec, debug_count%1000000);
84 printf("\033[32m%06d %s\033[37m%s", debug_count%1000000, prefix?prefix:"", prefix?" ":"");
86 printf("(in %s() line %d): %s", function, line, buffer);
91 if (options.deb&DEBUG_LOG && global_debug)
96 dprint(DBGM_MAN, 0, "%s%s(in %s() line %d): %s", prefix?prefix:"", prefix?" ":"", function, line, buffer);
98 dprint(DBGM_MAN, 0, "%s%s: %s", prefix?prefix:"", prefix?" ":"", buffer);
104 if (buffer[strlen(buffer)-1] == '\n')
108 void printlog(const char *fmt, ...)
114 pthread_mutex_lock(&mutexl);
117 VUNPRINT(buffer,sizeof(buffer)-1,fmt,args);
118 buffer[sizeof(buffer)-1]=0;
123 if (options.deb & DEBUG_LOG)
124 debug(NULL, 0, "LOG ->", buffer);
126 if ((fp = fopen(options.log, "a")))
129 fprintf(fp, "%04d.%02d.%02d %02d:%02d:%02d %s", now_tm->tm_year+1900, now_tm->tm_mon+1, now_tm->tm_mday, now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec, buffer);
135 pthread_mutex_unlock(&mutexl);
138 void _printdebug(const char *function, int line, unsigned long mask, const char *fmt, ...)
143 if (!(options.deb & mask))
145 pthread_mutex_lock(&mutexd);
148 VUNPRINT(buffer,sizeof(buffer)-1,fmt,args);
149 buffer[sizeof(buffer)-1]=0;
152 debug(function, line, debug_prefix, buffer);
154 pthread_mutex_unlock(&mutexd);
157 void _printerror(const char *function, int line, const char *fmt, ...)
162 pthread_mutex_lock(&mutexe);
165 VUNPRINT(buffer,sizeof(buffer)-1,fmt,args);
166 buffer[sizeof(buffer)-1]=0;
170 debug(function, line, "ERROR", buffer);
171 else /* only if we do not debug */
174 fprintf(stderr, "ERROR (in %s() line %d) %s", function, line, buffer);
176 fprintf(stderr, "ERROR %s", buffer);
179 pthread_mutex_unlock(&mutexe);
183 void sighandler(int sigset)
185 struct sched_param schedp;
187 if (sigset == SIGHUP)
189 if (sigset == SIGPIPE)
194 /* set scheduler & priority */
195 if (options.schedule > 1)
197 memset(&schedp, 0, sizeof(schedp));
198 schedp.sched_priority = 0;
199 sched_setscheduler(0, SCHED_OTHER, &schedp);
201 fprintf(stderr, "PBX: Signal received: %d\n", sigset);
202 PERROR("Signal received: %d\n", sigset);
211 #define ARGC (args.GetCount()+1)
212 #define ARGV(a) (args[a-1])
213 void PBXMain::Main(void)
215 PArgList &args = GetArguments();
218 #define ARGV(a) (argv[a])
219 int main(int argc, char *argv[])
223 int lockfd = -1; /* file lock */
224 struct message *message;
226 class Endpoint *epoint;
230 char prefix_string[64];
231 struct sched_param schedp;
232 char *debug_prefix = "alloc";
233 int created_mutexd = 0, created_mutexl = 0, created_mutexe = 0,
234 created_lock = 0, created_signal = 0, created_debug = 0;
235 #ifdef DEBUG_DURATION
236 time_t durationupdate;
237 double idle_duration, isdn_duration, port_duration, epoint_duration, call_duration, message_duration, admin_duration;
240 int idletime = 0, idlecheck = 0;
247 printf("\n** %s Version %s\n\n", NAME, VERSION_STRING);
254 printf("Usage: pbx (query | start | fork | rules | route)\n");
255 printf("query = Show available isdn ports.\n");
256 printf("start = Run pbx normally, abort with CTRL+C.\n");
257 printf("fork = Do daemon fork and run as background process.\n");
258 printf("interface = Get help of available interface syntax.\n");
259 printf("rules = Get help of available routing rule syntax.\n");
260 printf("rules [action] = Get individual help for given action.\n");
261 // printf("route = Show current routing as it is parsed.\n");
267 /* check if we have a jitter limit that makes sense */
268 if (ISDN_JITTERLIMIT < 256)
270 fprintf(stderr, "The ISDN_JITTERLIMIT must be at least 256 samples.\n");
277 /* check for root (real or effective) */
278 if (getuid() && geteuid())
280 fprintf(stderr, "Please run %s as super-user.\n", NAME);
285 if (pthread_mutex_init(&mutexd, NULL))
287 fprintf(stderr, "cannot create 'PDEBUG' mutex\n");
291 if (pthread_mutex_init(&mutexl, NULL))
293 fprintf(stderr, "cannot create 'printlog' mutex\n");
297 if (pthread_mutex_init(&mutexe, NULL))
299 fprintf(stderr, "cannot create 'PERROR' mutex\n");
305 if (!(strcasecmp(ARGV(1),"interface")))
313 if (!(strcasecmp(ARGV(1),"rules")))
323 /* query available isdn ports */
324 if (!(strcasecmp(ARGV(1),"query")))
332 if (read_options() == 0)
335 /* initialize stuff of the NT lib */
336 if (options.deb & DEBUG_STACK)
338 global_debug = 0xffffffff & ~DBGM_MSG;
339 // global_debug = DBGM_L3DATA;
341 global_debug = DBGM_MAN;
342 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
343 if (options.deb & DEBUG_LOG)
344 debug_init(global_debug, debug_log, debug_log, debug_log);
346 debug_init(global_debug, NULL, NULL, NULL);
351 /* read ruleset(s) */
352 if (!(ruleset_first = ruleset_parse()))
355 /* set pointer to main ruleset */
356 ruleset_main = getrulesetbyname("main");
359 fprintf(stderr, "\n***\n -> Missing 'main' ruleset, causing ALL calls to be disconnected.\n***\n\n");
360 PDEBUG(DEBUG_LOG, "Missing 'main' ruleset, causing ALL calls to be disconnected.\n");
365 /* query available isdn ports */
366 if (!(strcasecmp(ARGV(1),"route")))
368 ruleset_debug(ruleset_first);
374 /* do fork in special cases */
375 if (!(strcasecmp(ARGV(1),"fork")))
384 fprintf(stderr, "Cannot fork!\n");
399 fprintf(stderr, "Cannot fork!\n");
404 printf("PBX: Starting daemon.\n");
410 if (!!strcasecmp(ARGV(1),"start"))
415 /* create lock and lock! */
416 if ((lockfd = open("/var/run/pbx.lock", O_CREAT, 0)) < 0)
418 fprintf(stderr, "Cannot create lock file: /var/run/pbx.lock\n");
421 if (flock(lockfd, LOCK_EX|LOCK_NB) < 0)
423 if (errno == EWOULDBLOCK)
424 fprintf(stderr, "PBX: Another PBX process is running. Please kill the other one.\n");
425 else fprintf(stderr, "Locking process failed: errno=%d\n", errno);
430 /* initialize admin socket */
433 fprintf(stderr, "Unable to initialize admin socket.\n");
437 /* generate alaw / ulaw tables */
438 generate_tables(options.law);
440 /* load tones (if requested) */
441 if (fetch_tones() == 0)
443 fprintf(stderr, "Unable to fetch tones into memory.\n");
447 /* read interfaces and open ports */
448 if (!read_interfaces())
450 PERROR_RUNTIME("No interfaces specified or failed to parse interface.conf.\n");
451 fprintf(stderr, "No interfaces specified or failed to parse interface.conf.\n");
455 interface_first = interface_newlist;
456 free_interfaces(interface_newlist);
457 interface_newlist = NULL;
459 /* locking memory paging */
463 if (mlockall(MCL_CURRENT | MCL_FUTURE) >= 0)
473 fprintf(stderr, "Not enough memory to lock paging, exitting...\n");
476 fprintf(stderr, "No permission to lock paging, exitting...\n");
479 fprintf(stderr, "'Bad address' while locking paging, exitting...\n");
482 fprintf(stderr, "Unknown error %d while locking paging, exitting...\n", errno);
487 /* set real time scheduler & priority */
488 if (options.schedule > 1)
490 memset(&schedp, 0, sizeof(schedp));
491 schedp.sched_priority = options.schedule;
492 ret = sched_setscheduler(0, SCHED_RR, &schedp);
495 PERROR("Scheduling failed with given priority %d (errno = %d).\nCheck options.conf 'schedule', exitting...\n", options.schedule, errno);
500 /* signal handlers */
501 signal(SIGINT,sighandler);
502 signal(SIGHUP,sighandler);
503 signal(SIGTERM,sighandler);
504 signal(SIGPIPE,sighandler);
508 printf("%s %s started, waiting for calls...\n", NAME, VERSION_STRING);
509 printlog("%s %s started, waiting for calls...\n", NAME, VERSION_STRING);
511 #ifdef DEBUG_DURATION
513 durationupdate = now;
514 idle_duration = isdn_duration = port_duration = epoint_duration = call_duration = message_duration = admin_duration = 0;
519 /* all loops must be counted from the beginning since nodes might get freed during handler */
522 /* handle mISDN messages from kernel */
523 debug_prefix = "ISDN";
526 #ifdef DEBUG_DURATION
528 isdn_duration += (now_d - start_d);
533 /* loop through all port ports and call their handler */
538 debug_prefix = port->p_name;
540 ret = port->handler();
543 if (ret < 0) /* port has been destroyed */
547 #ifdef DEBUG_DURATION
549 port_duration += (now_d - start_d);
553 /* loop through all epoint and call their handler */
555 epoint = epoint_first;
558 debug_prefix = prefix_string;
559 SPRINT(prefix_string, "ep%ld", epoint->ep_serial);
561 ret = epoint->handler();
564 if (ret < 0) /* epoint has been destroyed */
566 epoint = epoint->next;
568 #ifdef DEBUG_DURATION
570 epoint_duration += (now_d - start_d);
574 /* loop through all calls and call their handler */
579 debug_prefix = "call";
581 ret = call->handler();
584 if (ret < 0) /* call has been destroyed */
588 #ifdef DEBUG_DURATION
590 call_duration += (now_d - start_d);
596 /* process any message */
598 debug_prefix = "message";
599 while ((message = message_get()))
602 switch(message->flow)
605 debug_prefix = "msg port->epoint";
606 epoint = find_epoint_id(message->id_to);
611 epoint->ep_app->ea_message_port(message->id_from, message->type, &message->param);
614 PDEBUG(DEBUG_MSG, "Warning: message %s from port %d to endpoint %d. endpoint doesn't have an application.\n", messages_txt[message->type], message->id_from, message->id_to);
618 PDEBUG(DEBUG_MSG, "Warning: message %s from port %d to endpoint %d. endpoint doesn't exist anymore.\n", messages_txt[message->type], message->id_from, message->id_to);
623 debug_prefix = "msg epoint->call";
624 call = find_call_id(message->id_to);
627 call->message_epoint(message->id_from, message->type, &message->param);
630 PDEBUG(DEBUG_MSG, "Warning: message %s from endpoint %d to call %d. call doesn't exist anymore\n", messages_txt[message->type], message->id_from, message->id_to);
635 debug_prefix = "msg call->epoint";
636 epoint = find_epoint_id(message->id_to);
641 epoint->ep_app->ea_message_call(message->id_from, message->type, &message->param);
644 PDEBUG(DEBUG_MSG, "Warning: message %s from call %d to endpoint %d. endpoint doesn't have an application.\n", messages_txt[message->type], message->id_from, message->id_to);
648 PDEBUG(DEBUG_MSG, "Warning: message %s from call %d to endpoint %d. endpoint doesn't exist anymore.\n", messages_txt[message->type], message->id_from, message->id_to);
653 debug_prefix = "msg epoint->port";
654 port = find_port_id(message->id_to);
657 port->message_epoint(message->id_from, message->type, &message->param);
661 PDEBUG(DEBUG_MSG, "Warning: message %s from endpoint %d to port %d. port doesn't exist anymore\n", messages_txt[message->type], message->id_from, message->id_to);
666 PERROR("Message flow %d unknown.\n", message->flow);
668 message_free(message);
670 debug_prefix = "message";
672 #ifdef DEBUG_DURATION
674 message_duration += (now_d - start_d);
682 #ifdef DEBUG_DURATION
684 admin_duration += (now_d - start_d);
690 /* check for child to exit (eliminate zombies) */
691 if (waitpid(-1, NULL, WNOHANG) > 0)
693 PDEBUG(DEBUG_EPOINT, "a child process (created by endpoint) has exitted.\n");
698 /* do idle checking */
699 if (idlecheck != now)
701 PDEBUG(DEBUG_IDLETIME, "Idle time : %d%%\n", idletime/10000);
705 #ifdef DEBUG_DURATION
707 idle_duration += (now_d - start_d);
709 if (durationupdate != now)
711 durationupdate = now;
712 printf("Idle:%3d ISDN:%3d Port:%3d Epoint:%3d Call:%3d Message:%3d Admin:%3d\n",
713 (int)(idle_duration*100),
714 (int)(isdn_duration*100),
715 (int)(port_duration*100),
716 (int)(epoint_duration*100),
717 (int)(call_duration*100),
718 (int)(message_duration*100),
719 (int)(admin_duration*100));
720 idle_duration = isdn_duration = port_duration = epoint_duration = call_duration = message_duration = admin_duration = 0;
726 /* did we do nothing? so we wait to give time to other processes */
729 usleep(4000); /* wait 32 samples */
733 printlog("PBX terminated\n");
740 /* set scheduler & priority
742 if (options.schedule > 1)
744 memset(&schedp, 0, sizeof(schedp));
745 schedp.sched_priority = 0;
746 sched_setscheduler(0, SCHED_OTHER, &schedp);
751 signal(SIGINT,SIG_DFL);
752 signal(SIGHUP,SIG_DFL);
753 signal(SIGTERM,SIG_DFL);
754 signal(SIGPIPE,SIG_DFL);
757 /* destroy objects */
758 debug_prefix = "free";
774 /* free interfaces */
776 free_interfaces(interface_first);
777 interface_first = NULL;
779 /* close isdn ports */
780 mISDNport_close_all();
785 while ((message = message_get()))
788 message_free(message);
792 PDEBUG(DEBUG_MSG, "freed %d pending messages\n", i);
799 /* free admin socket */
804 flock(lockfd, LOCK_UN);
810 ruleset_free(ruleset_first);
811 ruleset_first = NULL;
815 if (pthread_mutex_destroy(&mutexe))
816 fprintf(stderr, "cannot destroy 'PERROR' mutex\n");
818 if (pthread_mutex_destroy(&mutexl))
819 fprintf(stderr, "cannot destroy 'printlog' mutex\n");
821 if (pthread_mutex_destroy(&mutexd))
822 fprintf(stderr, "cannot destroy 'PDEBUG' mutex\n");
829 /* display memory leak */
830 #define MEMCHECK(a, b) \
833 printf("\n******************************\n\007"); \
834 printf("\nERROR: %d %s\n", b, a); \
835 printf("\n******************************\n"); \
839 MEMCHECK("memory block(s) left (port.cpp)",pmemuse)
840 MEMCHECK("memory block(s) left (epoint.cpp)",ememuse)
841 MEMCHECK("memory block(s) left (call.cpp)",cmemuse)
842 MEMCHECK("memory block(s) left (message.c)",mmemuse)
843 MEMCHECK("memory block(s) left (route.c)",rmemuse)
844 MEMCHECK("memory block(s) left (args)",amemuse)
845 MEMCHECK("class(es) left",classuse)
846 MEMCHECK("file descriptor(s) left",fduse)
847 MEMCHECK("file handler(s) left",fhuse)
851 printf("PBX: Exit (code %d)\n", ret);
861 /* special debug function to detect buffer overflow
863 int budetect_stop = 0;
864 void budetect(const char *file, int line, char *function)
868 /* modify this function to detect race-bugs */
869 #warning DID YOU MODIFY THIS FUNCTION TO DETECT THE BUFFER OVERFLOW BUG?
871 class PmISDN *pmisdn;
872 struct mISDNport *mISDNport = mISDNport_first;
878 ii = mISDNport->b_num;
881 if (mISDNport->b_port[i])
886 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_ISDN)
888 pmisdn = (class PmISDN *)port;
889 if (pmisdn->p_isdn_crypt_listen)
891 PERROR_RUNTIME("************************************************\n");
892 PERROR_RUNTIME("** BUG detected in %s, line %d, function %s\n", file, line, function);
893 PERROR_RUNTIME("** p_isdn_crypt_listen = %d\n", pmisdn->p_isdn_crypt_listen);
894 PERROR_RUNTIME("************************************************\n");
898 if (port == mISDNport->b_port[i])
903 PERROR_RUNTIME("************************************************\n");
904 PERROR_RUNTIME("** BUG detected in %s, line %d, function %s\n", file, line, function);
905 PERROR_RUNTIME("** b_port not in list.\n");
906 PERROR_RUNTIME("************************************************\n");
913 mISDNport = mISDNport->next;