blob: 6edb33d9e720576b14db7d4e109c456350fc5ede [file] [log] [blame]
//
// ipjsuaAppDelegate.m
// ipjsua
//
// Created by Liong Sauw Ming on 3/23/10.
// Copyright Teluu Inc. (http://www.teluu.com) 2010. All rights reserved.
//
#import <pjlib.h>
#import <pjsua.h>
#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