// // ipjsuaAppDelegate.m // ipjsua // // Created by Liong Sauw Ming on 3/23/10. // Copyright Teluu Inc. (http://www.teluu.com) 2010. All rights reserved. // #import #import #import "ipjsuaAppDelegate.h" extern pj_log_func *log_cb; @implementation ipjsuaAppDelegate @synthesize window; @synthesize tabBarController; @synthesize mainView; @synthesize cfgView; /* Sleep interval duration */ #define SLEEP_INTERVAL 0.5 /* Determine whether we should print the messages in the debugger * console as well */ #define DEBUGGER_PRINT 1 /* Whether we should show pj log messages in the text area */ #define SHOW_LOG 1 #define PATH_LENGTH PJ_MAXPATH #define KEEP_ALIVE_INTERVAL 600 extern pj_bool_t app_restart; char argv_buf[PATH_LENGTH]; char *argv[] = {"", "--config-file", argv_buf}; ipjsuaAppDelegate *app; bool app_running; bool thread_quit; NSMutableString *mstr; pj_thread_desc a_thread_desc; pj_thread_t *a_thread; pjsua_call_id ccall_id; pj_status_t app_init(int argc, char *argv[]); pj_status_t app_main(void); pj_status_t app_destroy(void); void keepAliveFunction(int timeout); void showMsg(const char *format, ...) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; va_list arg; va_start(arg, format); NSString *str = [[NSString alloc] initWithFormat:[NSString stringWithFormat:@"%s", format] arguments: arg]; #if DEBUGGER_PRINT NSLog(@"%@", str); #endif va_end(arg); [mstr appendString:str]; [pool release]; } char * getInput(char *s, int n, FILE *stream) { if (stream != stdin) { return fgets(s, n, stream); } app.mainView.hasInput = false; [app.mainView.textField setEnabled: true]; [app performSelectorOnMainThread:@selector(displayMsg:) withObject:mstr waitUntilDone:YES]; [mstr setString:@""]; while (!thread_quit && !app.mainView.hasInput) { int ctr = 0; [NSThread sleepForTimeInterval:SLEEP_INTERVAL]; if (ctr == 4) { [app performSelectorOnMainThread:@selector(displayMsg:) withObject:mstr waitUntilDone:YES]; [mstr setString:@""]; ctr = 0; } ctr++; } [app.mainView.text getCString:s maxLength:n encoding:NSASCIIStringEncoding]; [app.mainView.textField setEnabled: false]; [app performSelectorOnMainThread:@selector(displayMsg:) withObject:app.mainView.text waitUntilDone:NO]; return s; } void showLog(int level, const char *data, int len) { showMsg("%s", data); } pj_bool_t showNotification(pjsua_call_id call_id) { #ifdef __IPHONE_4_0 ccall_id = call_id; // Create a new notification NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; UILocalNotification* alert = [[[UILocalNotification alloc] init] autorelease]; if (alert) { alert.repeatInterval = 0; alert.alertBody = @"Incoming call received..."; alert.alertAction = @"Answer"; [[UIApplication sharedApplication] presentLocalNotificationNow:alert]; } [pool release]; return PJ_FALSE; #else return PJ_TRUE; #endif } - (void)answer_call { if (!pj_thread_is_registered()) { pj_thread_register("ipjsua", a_thread_desc, &a_thread); } pjsua_call_answer(ccall_id, 200, NULL, NULL); } #ifdef __IPHONE_4_0 - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { [app performSelectorOnMainThread:@selector(answer_call) withObject:nil waitUntilDone:YES]; } - (void)keepAlive { if (!pj_thread_is_registered()) { pj_thread_register("ipjsua", a_thread_desc, &a_thread); } keepAliveFunction(KEEP_ALIVE_INTERVAL); } - (void)applicationDidEnterBackground:(UIApplication *)application { [app performSelectorOnMainThread:@selector(keepAlive) withObject:nil waitUntilDone:YES]; [application setKeepAliveTimeout:KEEP_ALIVE_INTERVAL handler: ^{ [app performSelectorOnMainThread:@selector(keepAlive) withObject:nil waitUntilDone:YES]; }]; } #endif - (void)start_app { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; /* Wait until the view is ready */ while (self.mainView == nil) { [NSThread sleepForTimeInterval:SLEEP_INTERVAL]; } [NSThread setThreadPriority:1.0]; mstr = [NSMutableString stringWithCapacity:4196]; #if SHOW_LOG pj_log_set_log_func(&showLog); log_cb = &showLog; #endif do { app_restart = PJ_FALSE; if (app_init(3, argv) != PJ_SUCCESS) { NSString *str = @"Failed to initialize pjsua\n"; [app performSelectorOnMainThread:@selector(displayMsg:) withObject:str waitUntilDone:YES]; } else { app_running = true; app_main(); app_destroy(); /* This is on purpose */ app_destroy(); } [app performSelectorOnMainThread:@selector(displayMsg:) withObject:mstr waitUntilDone:YES]; [mstr setString:@""]; } while (app_restart); [pool release]; } - (void)displayMsg:(NSString *)str { self.mainView.textView.text = [self.mainView.textView.text stringByAppendingString:str]; [self.mainView.textView scrollRangeToVisible:NSMakeRange([self.mainView.textView.text length] - 1, 1)]; } - (void)applicationDidFinishLaunching:(UIApplication *)application { /* If there is no config file in the document dir, copy the default config file into the directory */ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *cfgPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"/config.cfg"]; if (![[NSFileManager defaultManager] fileExistsAtPath:cfgPath]) { NSString *resPath = [[NSBundle mainBundle] pathForResource:@"config" ofType:@"cfg"]; NSString *cfg = [NSString stringWithContentsOfFile:resPath encoding:NSASCIIStringEncoding error:NULL]; [cfg writeToFile:cfgPath atomically:NO encoding:NSASCIIStringEncoding error:NULL]; } [cfgPath getCString:argv[2] maxLength:PATH_LENGTH encoding:NSASCIIStringEncoding]; // Add the tab bar controller's current view as a subview of the window [window addSubview:tabBarController.view]; [window makeKeyAndVisible]; app = self; app_running = false; thread_quit = false; /* Start pjsua thread */ [NSThread detachNewThreadSelector:@selector(start_app) toTarget:self withObject:nil]; } /* // Optional UITabBarControllerDelegate method - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController { } */ /* // Optional UITabBarControllerDelegate method - (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed { } */ - (void)dealloc { thread_quit = true; [NSThread sleepForTimeInterval:SLEEP_INTERVAL]; [tabBarController release]; [window release]; [super dealloc]; } @end