summaryrefslogtreecommitdiff
path: root/pjsip-apps/src/ipjsua/Classes
diff options
context:
space:
mode:
Diffstat (limited to 'pjsip-apps/src/ipjsua/Classes')
-rw-r--r--pjsip-apps/src/ipjsua/Classes/ConfigViewController.h32
-rw-r--r--pjsip-apps/src/ipjsua/Classes/ConfigViewController.m158
-rw-r--r--pjsip-apps/src/ipjsua/Classes/FirstViewController.h37
-rw-r--r--pjsip-apps/src/ipjsua/Classes/FirstViewController.m107
-rw-r--r--pjsip-apps/src/ipjsua/Classes/TabBarController.h26
-rw-r--r--pjsip-apps/src/ipjsua/Classes/TabBarController.m30
-rw-r--r--pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.h37
-rw-r--r--pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.m252
8 files changed, 679 insertions, 0 deletions
diff --git a/pjsip-apps/src/ipjsua/Classes/ConfigViewController.h b/pjsip-apps/src/ipjsua/Classes/ConfigViewController.h
new file mode 100644
index 0000000..7764e65
--- /dev/null
+++ b/pjsip-apps/src/ipjsua/Classes/ConfigViewController.h
@@ -0,0 +1,32 @@
+/* $Id: ConfigViewController.h 3550 2011-05-05 05:33:27Z nanang $ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#import <UIKit/UIKit.h>
+
+
+@interface ConfigViewController : UIViewController {
+ IBOutlet UITextView *textView;
+ IBOutlet UIButton *button1;
+ IBOutlet UIButton *button2;
+}
+
+@property (nonatomic, retain) IBOutlet UITextView *textView;
+@property (nonatomic, retain) IBOutlet UIButton *button1;
+@property (nonatomic, retain) IBOutlet UIButton *button2;
+
+@end
diff --git a/pjsip-apps/src/ipjsua/Classes/ConfigViewController.m b/pjsip-apps/src/ipjsua/Classes/ConfigViewController.m
new file mode 100644
index 0000000..686ad44
--- /dev/null
+++ b/pjsip-apps/src/ipjsua/Classes/ConfigViewController.m
@@ -0,0 +1,158 @@
+/* $Id: ConfigViewController.m 3550 2011-05-05 05:33:27Z nanang $ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#import "ConfigViewController.h"
+#import "ipjsuaAppDelegate.h"
+
+
+@implementation ConfigViewController
+@synthesize textView;
+@synthesize button1;
+@synthesize button2;
+
+bool kshow = false;
+
+/*
+ // The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
+ if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
+ // Custom initialization
+ }
+ return self;
+}
+*/
+
+/*
+// Implement loadView to create a view hierarchy programmatically, without using a nib.
+- (void)loadView {
+}
+*/
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ // Dismiss the keyboard when the view outside the text view is touched.
+ [textView resignFirstResponder];
+ [super touchesBegan:touches withEvent:event];
+}
+
+// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ [textView setFont:[UIFont fontWithName:@"Courier" size:10]];
+ ipjsuaAppDelegate *appd = (ipjsuaAppDelegate *)[[UIApplication sharedApplication] delegate];
+ appd.cfgView = self;
+
+ /* Load config file and display it in the text view */
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString *cfgPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"/config.cfg"];
+ textView.text = [NSMutableString stringWithContentsOfFile:cfgPath encoding:NSASCIIStringEncoding error:NULL];
+
+ /* Add keyboard show/hide notifications so that we can resize the text view */
+ kshow = false;
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
+ [nc addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil];
+ [nc addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil];
+
+ /* Add button press event-handlers */
+ [self.button1 addTarget:self action:@selector(button1Pressed:) forControlEvents:(UIControlEvents)UIControlEventTouchDown];
+ [self.button2 addTarget:self action:@selector(button2Pressed:) forControlEvents:(UIControlEvents)UIControlEventTouchDown];
+}
+
+-(void) keyboardWillShow:(NSNotification *) note
+{
+ if (kshow) return;
+
+ /* Shrink the text view area when the keyboard appears */
+ [UIView beginAnimations:nil context:NULL];
+ [UIView setAnimationDuration:0.3];
+ CGRect r = self.textView.frame, t;
+ [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &t];
+ r.size.height -= t.size.height - 51;
+ self.textView.frame = r;
+ [UIView commitAnimations];
+ kshow = true;
+
+ [self.button1 setEnabled:true];
+ [self.button1.titleLabel setEnabled:true];
+ [self.button2 setEnabled:true];
+ [self.button2.titleLabel setEnabled:true];
+}
+
+-(void) keyboardWillHide:(NSNotification *) note
+{
+ CGRect r = self.textView.frame, t;
+ [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &t];
+ r.size.height += t.size.height - 51;
+ self.textView.frame = r;
+ kshow = false;
+}
+
+- (void)button1Pressed:(id)sender {
+ /* Save the config file */
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString *cfgPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"/config.cfg"];
+ [self.textView.text writeToFile:cfgPath atomically:NO encoding:NSASCIIStringEncoding error:NULL];
+
+ [self.textView resignFirstResponder];
+ [self.button1 setEnabled:false];
+ [self.button1.titleLabel setEnabled:false];
+ [self.button2 setEnabled:false];
+ [self.button2.titleLabel setEnabled:false];
+}
+
+- (void)button2Pressed:(id)sender {
+ /* Reload the config file */
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString *cfgPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"/config.cfg"];
+ self.textView.text = [NSMutableString stringWithContentsOfFile:cfgPath encoding:NSASCIIStringEncoding error:NULL];
+
+ [self.textView resignFirstResponder];
+ [self.button1 setEnabled:false];
+ [self.button1.titleLabel setEnabled:false];
+ [self.button2 setEnabled:false];
+ [self.button2.titleLabel setEnabled:false];
+}
+
+/*
+// Override to allow orientations other than the default portrait orientation.
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ // Return YES for supported orientations
+ return (interfaceOrientation == UIInterfaceOrientationPortrait);
+}
+*/
+
+- (void)didReceiveMemoryWarning {
+ // Releases the view if it doesn't have a superview.
+ [super didReceiveMemoryWarning];
+
+ // Release any cached data, images, etc that aren't in use.
+}
+
+- (void)viewDidUnload {
+ // Release any retained subviews of the main view.
+ // e.g. self.myOutlet = nil;
+}
+
+
+- (void)dealloc {
+ [super dealloc];
+}
+
+
+@end
diff --git a/pjsip-apps/src/ipjsua/Classes/FirstViewController.h b/pjsip-apps/src/ipjsua/Classes/FirstViewController.h
new file mode 100644
index 0000000..e418a1c
--- /dev/null
+++ b/pjsip-apps/src/ipjsua/Classes/FirstViewController.h
@@ -0,0 +1,37 @@
+/* $Id: FirstViewController.h 3550 2011-05-05 05:33:27Z nanang $ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#import <UIKit/UIKit.h>
+
+
+@interface FirstViewController : UIViewController<UITextFieldDelegate> {
+ IBOutlet UITextField *textField;
+ IBOutlet UITextView *textView;
+ IBOutlet UIButton *button1;
+
+ NSString *text;
+ bool hasInput;
+}
+
+@property (nonatomic, retain) IBOutlet UITextField *textField;
+@property (nonatomic, retain) IBOutlet UITextView *textView;
+@property (nonatomic, retain) IBOutlet UIButton *button1;
+@property (nonatomic, retain) NSString *text;
+@property (nonatomic) bool hasInput;
+
+@end
diff --git a/pjsip-apps/src/ipjsua/Classes/FirstViewController.m b/pjsip-apps/src/ipjsua/Classes/FirstViewController.m
new file mode 100644
index 0000000..8edbb05
--- /dev/null
+++ b/pjsip-apps/src/ipjsua/Classes/FirstViewController.m
@@ -0,0 +1,107 @@
+/* $Id: FirstViewController.m 3550 2011-05-05 05:33:27Z nanang $ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#import "FirstViewController.h"
+#import "ipjsuaAppDelegate.h"
+
+
+@implementation FirstViewController
+@synthesize textField;
+@synthesize textView;
+@synthesize button1;
+@synthesize text;
+@synthesize hasInput;
+
+- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
+ // When the user presses return, take focus away from the text field so that the keyboard is dismissed.
+ if (theTextField == textField) {
+ [self.textField resignFirstResponder];
+ self.hasInput = true;
+ self.text = [textField.text stringByAppendingString:@"\n"];
+ textField.text = @"";
+ }
+ return YES;
+}
+
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ // Dismiss the keyboard when the view outside the text field is touched.
+ [textField resignFirstResponder];
+ [super touchesBegan:touches withEvent:event];
+}
+
+/*
+// The designated initializer. Override to perform setup that is required before the view is loaded.
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
+ if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
+ // Custom initialization
+ }
+ return self;
+}
+*/
+
+/*
+// Implement loadView to create a view hierarchy programmatically, without using a nib.
+- (void)loadView {
+}
+*/
+
+// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
+
+ ipjsuaAppDelegate *appd = (ipjsuaAppDelegate *)[[UIApplication sharedApplication] delegate];
+ appd.mainView = self;
+ textField.delegate = self;
+ [self.textView setFont:[UIFont fontWithName:@"Courier New" size:8.9]];
+ [self.textField setEnabled: false];
+ [button1 addTarget:self action:@selector(button1Pressed:) forControlEvents:(UIControlEvents)UIControlEventTouchDown];
+}
+
+- (void)button1Pressed:(id)sender {
+ /* Clear the text view */
+ self.textView.text = @"";
+}
+
+// Override to allow orientations other than the default portrait orientation.
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ // Return YES for supported orientations
+ return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
+}
+
+- (void)didReceiveMemoryWarning {
+ // Releases the view if it doesn't have a superview.
+ [super didReceiveMemoryWarning];
+
+ // Release any cached data, images, etc that aren't in use.
+}
+
+- (void)viewDidUnload {
+ // Release any retained subviews of the main view.
+ // e.g. self.myOutlet = nil;
+}
+
+
+- (void)dealloc {
+ [super dealloc];
+}
+
+@end
diff --git a/pjsip-apps/src/ipjsua/Classes/TabBarController.h b/pjsip-apps/src/ipjsua/Classes/TabBarController.h
new file mode 100644
index 0000000..d960f99
--- /dev/null
+++ b/pjsip-apps/src/ipjsua/Classes/TabBarController.h
@@ -0,0 +1,26 @@
+/* $Id: TabBarController.h 3550 2011-05-05 05:33:27Z nanang $ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#import <UIKit/UIKit.h>
+
+
+@interface TabBarController : UITabBarController {
+
+}
+
+@end
diff --git a/pjsip-apps/src/ipjsua/Classes/TabBarController.m b/pjsip-apps/src/ipjsua/Classes/TabBarController.m
new file mode 100644
index 0000000..96b6279
--- /dev/null
+++ b/pjsip-apps/src/ipjsua/Classes/TabBarController.m
@@ -0,0 +1,30 @@
+/* $Id: TabBarController.m 3550 2011-05-05 05:33:27Z nanang $ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#import "TabBarController.h"
+
+
+@implementation TabBarController
+
+// Override to allow orientations other than the default portrait orientation.
+- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ // Return YES for supported orientations
+ return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
+}
+
+@end
diff --git a/pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.h b/pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.h
new file mode 100644
index 0000000..caf2f5d
--- /dev/null
+++ b/pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.h
@@ -0,0 +1,37 @@
+/* $Id: ipjsuaAppDelegate.h 3550 2011-05-05 05:33:27Z nanang $ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#import <UIKit/UIKit.h>
+#import "ConfigViewController.h"
+#import "FirstViewController.h"
+#import "TabBarController.h"
+
+@interface ipjsuaAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
+ UIWindow *window;
+ ConfigViewController *cfgView;
+ FirstViewController *mainView;
+ TabBarController *tabBarController;
+}
+
+@property (nonatomic, retain) IBOutlet UIWindow *window;
+@property (nonatomic, retain) IBOutlet TabBarController *tabBarController;
+@property (nonatomic, retain) IBOutlet ConfigViewController *cfgView;
+@property (nonatomic, retain) FirstViewController *mainView;
+
+
+@end
diff --git a/pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.m b/pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.m
new file mode 100644
index 0000000..c60084d
--- /dev/null
+++ b/pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.m
@@ -0,0 +1,252 @@
+/* $Id: ipjsuaAppDelegate.m 3550 2011-05-05 05:33:27Z nanang $ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#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
+