1 /*****************************************************************************\
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
53 PMutex mutex_h323; // mutual exclude threads when using OpenH323
57 class PBXMain : public PProcess
59 PCLASSINFO(PBXMain, PProcess)
66 PCREATE_PROCESS(PBXMain)
68 PBXMain::PBXMain(void) : PProcess("Jolly", "LinuxPBX", 0, 1, AlphaCode, 1)
72 PBXMain::~PBXMain(void)
78 H323_ep *h323_ep = NULL;
81 OpalManager *opal_mgr = NULL;
96 char *debug_prefix = 0;
99 int debug_newline = 1;
102 static void debug(const char *function, int line, char *prefix, char *buffer)
104 /* if we have a new debug count, we add a mark */
105 if (last_debug != debug_count)
107 last_debug = debug_count;
109 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);
110 if (options.deb&DEBUG_LOG && global_debug)
111 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);
117 printf("\033[32m%06d %s\033[37m%s", debug_count%1000000, prefix?prefix:"", prefix?" ":"");
119 printf("(in %s() line %d): %s", function, line, buffer);
121 printf("%s", buffer);
124 if (options.deb&DEBUG_LOG && global_debug)
129 dprint(DBGM_MAN, 0, "%s%s(in %s() line %d): %s", prefix?prefix:"", prefix?" ":"", function, line, buffer);
131 dprint(DBGM_MAN, 0, "%s%s: %s", prefix?prefix:"", prefix?" ":"", buffer);
137 if (buffer[strlen(buffer)-1] == '\n')
141 void printlog(const char *fmt, ...)
147 pthread_mutex_lock(&mutexl);
150 VUNPRINT(buffer,sizeof(buffer)-1,fmt,args);
151 buffer[sizeof(buffer)-1]=0;
156 if (options.deb & DEBUG_LOG)
157 debug(NULL, 0, "LOG ->", buffer);
159 if ((fp = fopen(options.log, "a")))
162 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);
168 pthread_mutex_unlock(&mutexl);
171 void _printdebug(const char *function, int line, unsigned long mask, const char *fmt, ...)
176 if (!(options.deb & mask))
178 pthread_mutex_lock(&mutexd);
181 VUNPRINT(buffer,sizeof(buffer)-1,fmt,args);
182 buffer[sizeof(buffer)-1]=0;
185 debug(function, line, debug_prefix, buffer);
187 pthread_mutex_unlock(&mutexd);
190 void _printerror(const char *function, int line, const char *fmt, ...)
195 pthread_mutex_lock(&mutexe);
198 VUNPRINT(buffer,sizeof(buffer)-1,fmt,args);
199 buffer[sizeof(buffer)-1]=0;
203 debug(function, line, "ERROR", buffer);
204 else /* only if we do not debug */
207 fprintf(stderr, "ERROR (in %s() line %d) %s", function, line, buffer);
209 fprintf(stderr, "ERROR %s", buffer);
212 pthread_mutex_unlock(&mutexe);
216 void sighandler(int sigset)
218 struct sched_param schedp;
220 if (sigset == SIGHUP)
222 if (sigset == SIGPIPE)
227 /* set scheduler & priority */
228 if (options.schedule > 1)
230 memset(&schedp, 0, sizeof(schedp));
231 schedp.sched_priority = 0;
232 sched_setscheduler(0, SCHED_OTHER, &schedp);
234 fprintf(stderr, "PBX: Signal received: %d\n", sigset);
235 PERROR("Signal received: %d\n", sigset);
244 #define ARGC (args.GetCount()+1)
245 #define ARGV(a) (args[a-1])
246 void PBXMain::Main(void)
248 PArgList &args = GetArguments();
251 #define ARGV(a) (argv[a])
252 int main(int argc, char *argv[])
256 int lockfd = -1; /* file lock */
257 struct message *message;
259 class Endpoint *epoint;
263 char prefix_string[64];
264 struct sched_param schedp;
265 char *debug_prefix = "alloc";
266 int created_mutexd = 0, created_mutexl = 0, created_mutexe = 0,
267 created_lock = 0, created_signal = 0, created_debug = 0;
268 #ifdef DEBUG_DURATION
269 time_t durationupdate;
270 double idle_duration, isdn_duration, port_duration, epoint_duration, call_duration, message_duration, admin_duration;
273 int idletime = 0, idlecheck = 0;
281 printf("\n** %s Version %s (with OPAL)\n\n", NAME, VERSION_STRING);
284 printf("\n** %s Version %s (with H323)\n\n", NAME, VERSION_STRING);
286 printf("\n** %s Version %s\n\n", NAME, VERSION_STRING);
295 printf("Usage: pbx (query | start | fork | rules | route)\n");
296 printf("query = Show available isdn ports.\n");
297 printf("start = Run pbx normally, abort with CTRL+C.\n");
298 printf("fork = Do daemon fork and run as background process.\n");
299 printf("interface = Get help of available interface syntax.\n");
300 printf("rules = Get help of available routing rule syntax.\n");
301 printf("rules [action] = Get individual help for given action.\n");
302 // printf("route = Show current routing as it is parsed.\n");
308 /* check if we have a jitter limit that makes sense */
309 if (ISDN_JITTERLIMIT < 256)
311 fprintf(stderr, "The ISDN_JITTERLIMIT must be at least 256 samples.\n");
318 /* check for root (real or effective) */
319 if (getuid() && geteuid())
321 fprintf(stderr, "Please run %s as super-user.\n", NAME);
326 if (pthread_mutex_init(&mutexd, NULL))
328 fprintf(stderr, "cannot create 'PDEBUG' mutex\n");
332 if (pthread_mutex_init(&mutexl, NULL))
334 fprintf(stderr, "cannot create 'printlog' mutex\n");
338 if (pthread_mutex_init(&mutexe, NULL))
340 fprintf(stderr, "cannot create 'PERROR' mutex\n");
346 if (!(strcasecmp(ARGV(1),"interface")))
354 if (!(strcasecmp(ARGV(1),"rules")))
364 /* query available isdn ports */
365 if (!(strcasecmp(ARGV(1),"query")))
373 if (read_options() == 0)
376 /* initialize stuff of the NT lib */
377 if (options.deb & DEBUG_STACK)
379 global_debug = 0xffffffff & ~DBGM_MSG;
380 // global_debug = DBGM_L3DATA;
382 global_debug = DBGM_MAN;
383 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
384 if (options.deb & DEBUG_LOG)
385 debug_init(global_debug, debug_log, debug_log, debug_log);
387 debug_init(global_debug, NULL, NULL, NULL);
392 /* read ruleset(s) */
393 if (!(ruleset_first = ruleset_parse()))
396 /* set pointer to main ruleset */
397 ruleset_main = getrulesetbyname("main");
400 fprintf(stderr, "\n***\n -> Missing 'main' ruleset, causing ALL calls to be disconnected.\n***\n\n");
401 PDEBUG(DEBUG_LOG, "Missing 'main' ruleset, causing ALL calls to be disconnected.\n");
406 /* query available isdn ports */
407 if (!(strcasecmp(ARGV(1),"route")))
409 ruleset_debug(ruleset_first);
415 /* do fork in special cases */
416 if (!(strcasecmp(ARGV(1),"fork")))
425 fprintf(stderr, "Cannot fork!\n");
440 fprintf(stderr, "Cannot fork!\n");
445 printf("PBX: Starting daemon.\n");
451 if (!!strcasecmp(ARGV(1),"start"))
456 /* create lock and lock! */
457 if ((lockfd = open("/var/run/pbx.lock", O_CREAT, 0)) < 0)
459 fprintf(stderr, "Cannot create lock file: /var/run/pbx.lock\n");
462 if (flock(lockfd, LOCK_EX|LOCK_NB) < 0)
464 if (errno == EWOULDBLOCK)
465 fprintf(stderr, "PBX: Another PBX process is running. Please kill the other one.\n");
466 else fprintf(stderr, "Locking process failed: errno=%d\n", errno);
471 /* initialize admin socket */
474 fprintf(stderr, "Unable to initialize admin socket.\n");
478 /* generate alaw / ulaw tables */
479 generate_tables(options.law);
481 /* load tones (if requested) */
482 if (fetch_tones() == 0)
484 fprintf(stderr, "Unable to fetch tones into memory.\n");
489 /* create OPAL manager */
490 opal_mgr = new PBXManager;
493 fprintf(stderr, "Unable to create OPAL manager.\n");
496 if (opal_mgr->Initialise())
498 todo thread kreieren...
506 // create h323 endpoint and initialize
507 h323_ep = new H323_ep();
510 fprintf(stderr, "Unable to create h323 endpoint.\n");
513 if (h323_ep->Init() == FALSE)
515 fprintf(stderr, "Unable to init h323 endpoint.\n");
521 /* read interfaces and open ports */
522 if (!read_interfaces())
524 PERROR_RUNTIME("No interfaces specified or failed to parse interface.conf.\n");
525 fprintf(stderr, "No interfaces specified or failed to parse interface.conf.\n");
529 interface_first = interface_newlist;
530 free_interfaces(interface_newlist);
531 interface_newlist = NULL;
533 /* locking memory paging */
537 if (mlockall(MCL_CURRENT | MCL_FUTURE) >= 0)
547 fprintf(stderr, "Not enough memory to lock paging, exitting...\n");
550 fprintf(stderr, "No permission to lock paging, exitting...\n");
553 fprintf(stderr, "'Bad address' while locking paging, exitting...\n");
556 fprintf(stderr, "Unknown error %d while locking paging, exitting...\n", errno);
561 /* set real time scheduler & priority */
562 if (options.schedule > 1)
564 memset(&schedp, 0, sizeof(schedp));
565 schedp.sched_priority = options.schedule;
566 ret = sched_setscheduler(0, SCHED_RR, &schedp);
569 PERROR("Scheduling failed with given priority %d (errno = %d).\nCheck options.conf 'schedule', exitting...\n", options.schedule, errno);
574 /* signal handlers */
575 signal(SIGINT,sighandler);
576 signal(SIGHUP,sighandler);
577 signal(SIGTERM,sighandler);
578 signal(SIGPIPE,sighandler);
582 printf("%s %s started, waiting for calls...\n", NAME, VERSION_STRING);
583 printlog("%s %s started, waiting for calls...\n", NAME, VERSION_STRING);
585 #ifdef DEBUG_DURATION
587 durationupdate = now;
588 idle_duration = isdn_duration = port_duration = epoint_duration = call_duration = message_duration = admin_duration = 0;
593 /* all loops must be counted from the beginning since nodes might get freed during handler */
600 /* handle mISDN messages from kernel */
601 debug_prefix = "ISDN";
604 #ifdef DEBUG_DURATION
606 isdn_duration += (now_d - start_d);
611 /* loop through all port ports and call their handler */
616 debug_prefix = port->p_name;
618 ret = port->handler();
621 if (ret < 0) /* port has been destroyed */
625 #ifdef DEBUG_DURATION
627 port_duration += (now_d - start_d);
631 /* loop through all epoint and call their handler */
633 epoint = epoint_first;
636 debug_prefix = prefix_string;
637 SPRINT(prefix_string, "ep%ld", epoint->ep_serial);
639 ret = epoint->handler();
642 if (ret < 0) /* epoint has been destroyed */
644 epoint = epoint->next;
646 #ifdef DEBUG_DURATION
648 epoint_duration += (now_d - start_d);
652 /* loop through all calls and call their handler */
657 debug_prefix = "call";
659 ret = call->handler();
662 if (ret < 0) /* call has been destroyed */
666 #ifdef DEBUG_DURATION
668 call_duration += (now_d - start_d);
674 /* process any message */
676 debug_prefix = "message";
677 while ((message = message_get()))
680 switch(message->flow)
683 debug_prefix = "msg port->epoint";
684 epoint = find_epoint_id(message->id_to);
689 epoint->ep_app->ea_message_port(message->id_from, message->type, &message->param);
692 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);
696 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);
701 debug_prefix = "msg epoint->call";
702 call = find_call_id(message->id_to);
705 call->message_epoint(message->id_from, message->type, &message->param);
708 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);
713 debug_prefix = "msg call->epoint";
714 epoint = find_epoint_id(message->id_to);
719 epoint->ep_app->ea_message_call(message->id_from, message->type, &message->param);
722 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);
726 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);
731 debug_prefix = "msg epoint->port";
732 port = find_port_id(message->id_to);
735 port->message_epoint(message->id_from, message->type, &message->param);
739 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);
744 PERROR("Message flow %d unknown.\n", message->flow);
746 message_free(message);
748 debug_prefix = "message";
750 #ifdef DEBUG_DURATION
752 message_duration += (now_d - start_d);
760 #ifdef DEBUG_DURATION
762 admin_duration += (now_d - start_d);
768 /* check for child to exit (eliminate zombies) */
769 if (waitpid(-1, NULL, WNOHANG) > 0)
771 PDEBUG(DEBUG_EPOINT, "a child process (created by endpoint) has exitted.\n");
776 /* do idle checking */
777 if (idlecheck != now)
779 PDEBUG(DEBUG_IDLETIME, "Idle time : %d%%\n", idletime/10000);
783 #ifdef DEBUG_DURATION
785 idle_duration += (now_d - start_d);
787 if (durationupdate != now)
789 durationupdate = now;
790 printf("Idle:%3d ISDN:%3d Port:%3d Epoint:%3d Call:%3d Message:%3d Admin:%3d\n",
791 (int)(idle_duration*100),
792 (int)(isdn_duration*100),
793 (int)(port_duration*100),
794 (int)(epoint_duration*100),
795 (int)(call_duration*100),
796 (int)(message_duration*100),
797 (int)(admin_duration*100));
798 idle_duration = isdn_duration = port_duration = epoint_duration = call_duration = message_duration = admin_duration = 0;
805 // NOTE: be carefull with this, don't do anything after unlocking except sleeping and locking!
806 debug_prefix = "h323";
810 /* did we do nothing? so we wait to give time to other processes */
813 usleep(4000); /* wait 32 samples */
817 printlog("PBX terminated\n");
824 /* set scheduler & priority
825 * we must remove realtimeshed, because h323 may lock during exit
827 if (options.schedule > 1)
829 memset(&schedp, 0, sizeof(schedp));
830 schedp.sched_priority = 0;
831 sched_setscheduler(0, SCHED_OTHER, &schedp);
836 signal(SIGINT,SIG_DFL);
837 signal(SIGHUP,SIG_DFL);
838 signal(SIGTERM,SIG_DFL);
839 signal(SIGPIPE,SIG_DFL);
842 /* destroy objects */
846 debug_prefix = "free";
862 /* free interfaces */
864 free_interfaces(interface_first);
865 interface_first = NULL;
867 /* close isdn ports */
868 mISDNport_close_all();
873 while ((message = message_get()))
876 message_free(message);
880 PDEBUG(DEBUG_MSG, "freed %d pending messages\n", i);
888 /* destroy manager */
891 todo kill an den main-thread von opal und warten...
892 if (options.deb & DEBUG_OPAL)
893 printf("->now deleting opal manager\n");
895 if (options.deb & DEBUG_OPAL)
896 printf("->opal manager deleted\n");
902 /* destroy endpoint */
905 if (options.deb & DEBUG_H323)
906 printf("->now deleting endpoint\n");
908 if (options.deb & DEBUG_H323)
909 printf("->endpoint deleted\n");
918 /* free admin socket */
923 flock(lockfd, LOCK_UN);
929 ruleset_free(ruleset_first);
930 ruleset_first = NULL;
934 if (pthread_mutex_destroy(&mutexe))
935 fprintf(stderr, "cannot destroy 'PERROR' mutex\n");
937 if (pthread_mutex_destroy(&mutexl))
938 fprintf(stderr, "cannot destroy 'printlog' mutex\n");
940 if (pthread_mutex_destroy(&mutexd))
941 fprintf(stderr, "cannot destroy 'PDEBUG' mutex\n");
948 /* display memory leak */
949 #define MEMCHECK(a, b) \
952 printf("\n******************************\n\007"); \
953 printf("\nERROR: %d %s\n", b, a); \
954 printf("\n******************************\n"); \
958 MEMCHECK("memory block(s) left (port.cpp)",pmemuse)
959 MEMCHECK("memory block(s) left (epoint.cpp)",ememuse)
960 MEMCHECK("memory block(s) left (call.cpp)",cmemuse)
961 MEMCHECK("memory block(s) left (message.c)",mmemuse)
962 MEMCHECK("memory block(s) left (route.c)",rmemuse)
963 MEMCHECK("memory block(s) left (args)",amemuse)
964 MEMCHECK("class(es) left",classuse)
965 MEMCHECK("file descriptor(s) left",fduse)
966 MEMCHECK("file handler(s) left",fhuse)
970 printf("PBX: Exit (code %d)\n", ret);
980 /* special debug function to detect buffer overflow
982 int budetect_stop = 0;
983 void budetect(const char *file, int line, char *function)
987 /* modify this function to detect race-bugs */
988 #warning DID YOU MODIFY THIS FUNCTION TO DETECT THE BUFFER OVERFLOW BUG?
990 class PmISDN *pmisdn;
991 struct mISDNport *mISDNport = mISDNport_first;
997 ii = mISDNport->b_num;
1000 if (mISDNport->b_port[i])
1005 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_ISDN)
1007 pmisdn = (class PmISDN *)port;
1008 if (pmisdn->p_isdn_crypt_listen)
1010 PERROR_RUNTIME("************************************************\n");
1011 PERROR_RUNTIME("** BUG detected in %s, line %d, function %s\n", file, line, function);
1012 PERROR_RUNTIME("** p_isdn_crypt_listen = %d\n", pmisdn->p_isdn_crypt_listen);
1013 PERROR_RUNTIME("************************************************\n");
1017 if (port == mISDNport->b_port[i])
1022 PERROR_RUNTIME("************************************************\n");
1023 PERROR_RUNTIME("** BUG detected in %s, line %d, function %s\n", file, line, function);
1024 PERROR_RUNTIME("** b_port not in list.\n");
1025 PERROR_RUNTIME("************************************************\n");
1032 mISDNport = mISDNport->next;