Made it possible to enter sip addresses as a contact to call people on other SIP accounts. Fixed issue with MGMSound crashing. Fixed issue with people who might have case sensitive file systems. Made MGMSIP use TCP instead of UDP when available which appears to fix issue with unpluggin headphones. Added an extra handler for incoming calls so when a call isn't from the proper account, it'll find the proper one and assign it to that account. Added speaker support for iPhone. Fixed the tone generator so it only is created when needed for DTMF. Fixed leak when checking a SIP account. Fixed issue with ringtone playing when the call has been disconnected.

This commit is contained in:
GRMrGecko 2010-10-16 20:32:55 -05:00
parent a644448ef9
commit f7a808f394
21 changed files with 239 additions and 73 deletions

View File

@ -305,11 +305,11 @@ const int MGMCMaxResults = 10;
if (thePage==0) thePage = 1;
long long int page = (thePage*maxResults)-maxResults;
if (theString==nil || [string isEqual:@""]) {
result = [contactsConnection query:@"SELECT docid, * FROM contacts ORDER BY company, name LIMIT %qi, %i", page, maxResults];
result = [contactsConnection query:@"SELECT docid, * FROM contacts ORDER BY company, name LIMIT %qi, %d", page, maxResults];
} else {
if ([string isPhone]) {
NSString *search = [NSString stringWithFormat:MGMCNum, [[string removePhoneWhiteSpace] littersToNumbers]];
result = [contactsConnection query:@"SELECT docid, * FROM contacts WHERE number LIKE %@ ORDER BY company, name LIMIT %qi, %i", search, page, maxResults];
result = [contactsConnection query:@"SELECT docid, * FROM contacts WHERE number LIKE %@ ORDER BY company, name LIMIT %qi, %d", search, page, maxResults];
} else {
NSArray *words = [string componentsSeparatedByString:@" "];
NSMutableString *search = [NSMutableString string];
@ -339,7 +339,7 @@ const int MGMCMaxResults = 10;
}
}
}
result = [contactsConnection query:@"SELECT docid, *, offsets(contacts) AS offset FROM contacts WHERE contacts MATCH %@ ORDER BY offset LIMIT %qi, %i", search, page, maxResults];
result = [contactsConnection query:@"SELECT docid, *, offsets(contacts) AS offset FROM contacts WHERE contacts MATCH %@ ORDER BY offset LIMIT %qi, %d", search, page, maxResults];
}
}
NSDictionary *contact = nil;
@ -364,7 +364,7 @@ const int MGMCMaxResults = 10;
if ([string isPhone]) {
for (int i=0; i<2; i++) {
NSString *search = [NSString stringWithFormat:@"%@%%", (i==0 ? [string phoneFormat] : [string phoneFormatAreaCode:[delegate areaCode]])];
MGMLiteResult *result = [contactsConnection query:@"SELECT docid, * FROM contacts WHERE number LIKE %@ ORDER BY company, name LIMIT %i", search, maxResults];
MGMLiteResult *result = [contactsConnection query:@"SELECT docid, * FROM contacts WHERE number LIKE %@ ORDER BY company, name LIMIT %d", search, maxResults];
NSDictionary *contact = nil;
while ((contact=[result nextRow])!=nil) {
@ -399,7 +399,7 @@ const int MGMCMaxResults = 10;
[search appendFormat:MGMCWordSSA, word];
}
}
MGMLiteResult *result = [contactsConnection query:@"SELECT docid, *, offsets(contacts) AS offset FROM contacts WHERE contacts MATCH %@ ORDER BY offset LIMIT %i", search, maxResults];
MGMLiteResult *result = [contactsConnection query:@"SELECT docid, *, offsets(contacts) AS offset FROM contacts WHERE contacts MATCH %@ ORDER BY offset LIMIT %d", search, maxResults];
NSDictionary *contact = nil;
while ((contact=[result nextRow])!=nil) {
@ -481,7 +481,9 @@ const int MGMCMaxResults = 10;
else if (![[contact objectForKey:MGMCCompany] isEqual:@""])
return [contact objectForKey:MGMCCompany];
}
return [theNumber readableNumber];
if ([theNumber isPhone])
return [theNumber readableNumber];
return theNumber;
}
- (NSArray *)groups {

View File

@ -46,9 +46,9 @@ extern const int MGMIMissedType;
extern const int MGMIReceivedType;
extern const int MGMIVoicemailType;
extern const int MGMIRecordedType;
extern const int MGMIPlaced;
extern const int MGMISMSIn;
extern const int MGMISMSOut;
extern const int MGMIPlacedType;
extern const int MGMISMSInType;
extern const int MGMISMSOutType;
@interface MGMInbox : NSObject {
MGMInstance *instance;

View File

@ -60,9 +60,9 @@ const int MGMIMissedType = 0;
const int MGMIReceivedType = 1;
const int MGMIVoicemailType = 2;
const int MGMIRecordedType = 4;
const int MGMIPlaced = 8;
const int MGMISMSIn = 10;
const int MGMISMSOut = 11;
const int MGMIPlacedType = 8;
const int MGMISMSInType = 10;
const int MGMISMSOutType = 11;
NSString * const MGMIPage = @"%@?page=p%d";
@ -289,7 +289,7 @@ const BOOL MGMInboxInvisible = YES;
[transcript appendFormat:@" %@", [[words objectAtIndex:w] stringValue]];
}
[thisInfo setObject:transcript forKey:MGMIText];
} else if (type==MGMISMSIn || type==MGMISMSOut) {
} else if (type==MGMISMSInType || type==MGMISMSOutType) {
NSArray *messagesXML = [[message childAtIndex:0] nodesForXPath:[NSString stringWithFormat:@"/html[1]/body[1]/div[%d]/div[1]/div[2]/table[1]/tr[1]/td[3]/div[1]/table[1]/tr[2]/td[2]/table[1]/tr[2]/td[1]/div[1]/div[1]/table[1]/tr[1]/td[2]/div[1]/div[1]/div[1]/div", i+1] error:nil];
NSMutableArray *messagesArray = [NSMutableArray array];
for (unsigned int m=0; m<[messagesXML count]; m++) {

View File

@ -42,6 +42,7 @@
}
- (void)dealloc {
if (sound!=nil) {
[sound setDelegate:nil];
[sound stop];
[sound release];
}

View File

@ -22,7 +22,7 @@ NSString * const MGMTCurrentThemePath = @"MGMTCurrentThemePath";
NSString * const MGMTCurrentThemeVariant = @"MGMTCurrentThemeVariant";
NSString * const MGMTShowHeader = @"MGMTShowHeader";
NSString * const MGMTShowFooter = @"MGMTShowFooter";
NSString * const MGMTInfoPlist = @"info.plist";
NSString * const MGMTInfoPlist = @"Info.plist";
NSString * const MGMTPResource = @"%RESOURCE%";
NSString * const MGMTPThemes = @"%THEMES%";

View File

@ -94,7 +94,9 @@ typedef enum {
pjmedia_port *ringbackPort;
pjsua_conf_port_id ringbackSlot;
pjsua_transport_id UDPTransport;
pjsua_acc_id UDPAccount;
pjsua_transport_id TCPTransport;
pjsua_acc_id TCPAccount;
MGMSIPNATType NATType;
BOOL shouldRestart;
@ -130,6 +132,10 @@ typedef enum {
- (pjsua_media_config)mediaConfig;
- (pjmedia_port *)ringbackPort;
- (pjsua_conf_port_id)ringbackSlot;
- (pjsua_transport_id)UDPTransport;
- (pjsua_acc_id)UDPAccount;
- (pjsua_transport_id)TCPTransport;
- (pjsua_acc_id)TCPAccount;
- (MGMSIPNATType)NATType;
- (void)setNATType:(MGMSIPNATType)theNATType;
@ -139,13 +145,18 @@ typedef enum {
- (void)computerSleep;
- (void)computerWake;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
- (void)keepAlive;
#endif
- (void)registerThread:(pj_thread_desc *)thePJThreadDesc;
- (void)loginToAccount:(MGMSIPAccount *)theAccount;
- (void)logoutOfAccount:(MGMSIPAccount *)theAccount;
- (NSArray *)accounts;
- (MGMSIPAccount *)accountWithIdentifier:(int)theIdentifier;
- (pjsua_acc_id)accountIDForUserName:(NSString *)theUserName;
- (MGMSIPAccount *)accountWithIdentifier:(pjsua_acc_id)theIdentifier;
- (int)ringbackCount;
- (void)setRingbackCount:(int)theRingbackCount;
@ -167,6 +178,6 @@ typedef enum {
- (void)receivedNewCall:(MGMSIPCall *)theCall;
- (void)startingNewCall:(MGMSIPCall *)theCall;
- (NSArray *)calls;
- (MGMSIPCall *)callWithIdentifier:(int)theIdentifier;
- (MGMSIPCall *)callWithIdentifier:(pjsua_call_id)theIdentifier;
@end
#endif

View File

@ -10,7 +10,9 @@
#import "MGMSIP.h"
#import "MGMSIPAccount.h"
#import "MGMSIPCall.h"
#import "MGMSIPURL.h"
#import "MGMAddons.h"
#include <pjsua-lib/pjsua_internal.h>
#import <SystemConfiguration/SystemConfiguration.h>
#if !TARGET_OS_IPHONE
#import <CoreAudio/CoreAudio.h>
@ -20,6 +22,7 @@ NSString * const MGMSIPCopyright = @"Copyright (c) 2010 Mr. Gecko's Media (James
const int MGMSIPMaxCalls = 8;
const int MGMSIPDefaultOutboundProxyPort = 5060;
const int MGMSIPDefaultOutboundPort = 5060;
const int MGMSIPDefaultSTUNPort = 3478;
NSString * const MGMSIPOutboundProxy = @"MGMSIPOutboundProxy";
@ -64,7 +67,17 @@ static MGMSIP *MGMSIPSingleton = nil;
static void MGMSIPIncomingCallReceived(pjsua_acc_id accountIdentifier, pjsua_call_id callIdentifier, pjsip_rx_data *messageData) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
PJ_LOG(3, (THIS_FILE, "Incoming call for account %d!", accountIdentifier));
PJ_LOG(3, (THIS_FILE, "Incoming call %d for account %d", callIdentifier, accountIdentifier));
if (accountIdentifier==[[MGMSIP sharedSIP] UDPAccount] || accountIdentifier==[[MGMSIP sharedSIP] TCPAccount]) {
pjsua_call_info callInfo;
pj_status_t status = pjsua_call_get_info(callIdentifier, &callInfo);
if (status==PJ_SUCCESS) {
MGMSIPURL *localURL = [MGMSIPURL URLWithSIPID:[NSString stringWithPJString:callInfo.local_info]];
accountIdentifier = [[MGMSIP sharedSIP] accountIDForUserName:[localURL userName]];
}
}
MGMSIPAccount *account = [[MGMSIP sharedSIP] accountWithIdentifier:accountIdentifier];
MGMSIPCall *call = [account addCallWithIdentifier:callIdentifier];
[[MGMSIP sharedSIP] receivedNewCall:call];
@ -193,7 +206,7 @@ static void MGMSIPCallTransferStatusChanged(pjsua_call_id callIdentifier, int st
static void MGMSIPAccountRegistrationStateChanged(pjsua_acc_id accountIdentifier) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
MGMSIPAccount *account = [[MGMSIP sharedSIP] accountWithIdentifier:accountIdentifier];
if ([account delegate]!=nil && [[account delegate] respondsToSelector:@selector(registrationChanged)]) [[account delegate] registrationChanged];
if ([account delegate]!=nil && [[account delegate] respondsToSelector:@selector(registrationChanged)]) [(NSObject *)[account delegate] performSelectorOnMainThread:@selector(registrationChanged) withObject:nil waitUntilDone:NO];
[pool drain];
}
@ -351,6 +364,18 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
- (pjsua_conf_port_id)ringbackSlot {
return ringbackSlot;
}
- (pjsua_transport_id)UDPTransport {
return UDPTransport;
}
- (pjsua_acc_id)UDPAccount {
return UDPAccount;
}
- (pjsua_transport_id)TCPTransport {
return TCPTransport;
}
- (pjsua_acc_id)TCPAccount {
return TCPAccount;
}
- (MGMSIPNATType)NATType {
return NATType;
}
@ -503,7 +528,8 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
[pool drain];
return;
}
if (port == 0) {
pjsua_acc_add_local(UDPTransport, PJ_TRUE, &UDPAccount);
if (port==0) {
pjsua_transport_info transportInfo;
status = pjsua_transport_get_info(UDPTransport, &transportInfo);
if (status!=PJ_SUCCESS)
@ -514,8 +540,12 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
}
status = pjsua_transport_create(PJSIP_TRANSPORT_TCP, &transportConfig, &TCPTransport);
if (status!=PJ_SUCCESS)
if (status!=PJ_SUCCESS) {
NSLog(@"Error creating TCP transport");
} else {
pjsua_acc_add_local(TCPTransport, PJ_TRUE, &TCPAccount);
pjsua_acc_set_online_status(pjsua_acc_get_default(), PJ_TRUE);
}
status = pjsua_start();
if (status!=PJ_SUCCESS) {
@ -649,6 +679,22 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
}
}
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
- (void)keepAlive {
if (state==MGMSIPStartedState) {
pj_thread_desc PJThreadDesc;
[self registerThread:&PJThreadDesc];
for (int i=0; i<(int)pjsua_acc_get_count(); ++i) {
if (!pjsua_acc_is_valid(i))
continue;
pjsua_acc_set_registration(i, PJ_TRUE);
}
bzero(&PJThreadDesc, sizeof(pj_thread_desc));
}
}
#endif
- (void)registerThread:(pj_thread_desc *)thePJThreadDesc {
if (!pj_thread_is_registered()) {
pj_thread_t *PJThread;
@ -697,7 +743,8 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
accountConfig.id = [[NSString stringWithFormat:@"%@ <sip:%@>", [theAccount fullName], [theAccount SIPAddress]] PJString];
else
accountConfig.id = [[NSString stringWithFormat:@"<sip:%@>", [theAccount SIPAddress]] PJString];
accountConfig.reg_uri = [[NSString stringWithFormat:@"sip:%@", [theAccount registrar]] PJString];
NSString *registerURI = [NSString stringWithFormat:@"sip:%@", [theAccount registrar]];
accountConfig.reg_uri = [[registerURI stringByAppendingString:@";transport=tcp"] PJString];
if ([theAccount proxy]!=nil && ![[theAccount proxy] isEqual:@""]) {
accountConfig.proxy_cnt = 1;
@ -715,13 +762,17 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
pjsua_acc_id identifier;
pj_status_t status = pjsua_acc_add(&accountConfig, PJ_FALSE, &identifier);
if (status!=PJ_SUCCESS) {
[theAccount setLastError:[NSString stringWithFormat:@"Unable to login with status %d.", status]];
[theAccount loginErrored];
NSLog(@"Error With Account %@: %@", theAccount, [theAccount lastError]);
[accounts removeObject:theAccount];
bzero(&PJThreadDesc, sizeof(pj_thread_desc));
[pool drain];
return;
accountConfig.reg_uri = [registerURI PJString];
pj_status_t status = pjsua_acc_add(&accountConfig, PJ_FALSE, &identifier);
if (status!=PJ_SUCCESS) {
[theAccount setLastError:[NSString stringWithFormat:@"Unable to login with status %d.", status]];
[theAccount loginErrored];
NSLog(@"Error With Account %@: %@", theAccount, [theAccount lastError]);
[accounts removeObject:theAccount];
bzero(&PJThreadDesc, sizeof(pj_thread_desc));
[pool drain];
return;
}
}
[theAccount setIdentifier:identifier];
[theAccount setOnline:YES];
@ -744,6 +795,8 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
pj_thread_desc PJThreadDesc;
[self registerThread:&PJThreadDesc];
[theAccount setOnline:NO];
pj_status_t status = pjsua_acc_del([theAccount identifier]);
if (status!=PJ_SUCCESS) {
[theAccount setLastError:[NSString stringWithFormat:@"Unable to logout with status %d.", status]];
@ -753,8 +806,8 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
return;
}
[theAccount setIdentifier:PJSUA_INVALID_ID];
//if ([theAccount delegate]!=nil && [[theAccount delegate] respondsToSelector:@selector(loggedOut)]) [[theAccount delegate] loggedOut];
if (delegate!=nil && [delegate respondsToSelector:@selector(accountLoggedOut:)]) [delegate accountLoggedOut:theAccount];
if ([theAccount delegate]!=nil && [[theAccount delegate] respondsToSelector:@selector(loggedOut)]) [[theAccount delegate] loggedOut];
[accounts removeObject:theAccount];
bzero(&PJThreadDesc, sizeof(pj_thread_desc));
[pool drain];
@ -763,7 +816,31 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
- (NSArray *)accounts {
return accounts;
}
- (MGMSIPAccount *)accountWithIdentifier:(int)theIdentifier {
- (pjsua_acc_id)accountIDForUserName:(NSString *)theUserName {
for (int i=0; i<[accounts count]; i++) {
MGMSIPAccount *account = [accounts objectAtIndex:i];
if ([[[account userName] lowercaseString] isEqual:[theUserName lowercaseString]])
return [account identifier];
if ([[account userName] isPhone] && [[[account userName] phoneFormat] isEqual:[theUserName phoneFormat]])
return [account identifier];
pjsua_acc_info info;
pj_status_t status = pjsua_acc_get_info([account identifier], &info);
if (status==PJ_SUCCESS) {
MGMSIPURL *url = [MGMSIPURL URLWithSIPID:[NSString stringWithPJString:info.acc_uri]];
if ([[[url userName] lowercaseString] isEqual:[theUserName lowercaseString]])
return [account identifier];
if ([[url userName] isPhone] && [[[url userName] phoneFormat] isEqual:[theUserName phoneFormat]])
return [account identifier];
}
}
if ([accounts count]<=1)
return [[accounts objectAtIndex:0] identifier];
return PJSUA_INVALID_ID;
}
- (MGMSIPAccount *)accountWithIdentifier:(pjsua_acc_id)theIdentifier {
for (int i=0; i<[accounts count]; i++) {
if ([(MGMSIPAccount *)[accounts objectAtIndex:i] identifier]==theIdentifier)
return [accounts objectAtIndex:i];
@ -999,7 +1076,7 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
if (audioDevices!=nil) [audioDevices release];
audioDevices = [devicesArray copy];
if ((currentInput==-1 ? defaultInputIndex!=lastInputDevice : currentInput!=lastInputDevice) && (currentOutput==-1 ? defaultOutputIndex!=lastOutputDevice : currentOutput!=lastOutputDevice)) {
//if ((currentInput==-1 ? defaultInputIndex!=lastInputDevice : currentInput!=lastInputDevice) && (currentOutput==-1 ? defaultOutputIndex!=lastOutputDevice : currentOutput!=lastOutputDevice)) {
pj_thread_desc PJThreadDesc;
[self registerThread:&PJThreadDesc];
@ -1009,7 +1086,7 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
[self setInputSoundDevice:currentInput outputSoundDevice:currentOutput];
bzero(&PJThreadDesc, sizeof(pj_thread_desc));
}
//}
[[NSNotificationCenter defaultCenter] postNotificationName:MGMSIPAudioChangedNotification object:audioDevices];
@ -1033,7 +1110,7 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
[calls addObjectsFromArray:[[accounts objectAtIndex:i] calls]];
return calls;
}
- (MGMSIPCall *)callWithIdentifier:(int)theIdentifier {
- (MGMSIPCall *)callWithIdentifier:(pjsua_call_id)theIdentifier {
for (int i=0; i<[accounts count]; i++) {
MGMSIPCall *call = [[accounts objectAtIndex:i] callWithIdentifier:theIdentifier];
if (call!=nil)

View File

@ -12,6 +12,7 @@
#else
#import <Cocoa/Cocoa.h>
#endif
#import <pjsua-lib/pjsua.h>
extern NSString * const MGMSIPAccountFullName;
extern NSString * const MGMSIPAccountUserName;
@ -49,7 +50,7 @@ extern const int MGMSIPAccountDefaultProxyPort;
int reregisterTimeout;
NSTimer *reregisterTimer;
int identifier;
pjsua_acc_id identifier;
NSMutableArray *calls;
@ -78,8 +79,8 @@ extern const int MGMSIPAccountDefaultProxyPort;
- (void)setProxyPort:(int)theProxyPort;
- (int)reregisterTimeout;
- (void)setReregisterTimeout:(int)theReregisterTimeout;
- (int)identifier;
- (void)setIdentifier:(int)theIdentifier;
- (pjsua_acc_id)identifier;
- (void)setIdentifier:(pjsua_acc_id)theIdentifier;
- (NSString *)password;
- (NSDictionary *)settings;

View File

@ -83,8 +83,8 @@ const int MGMSIPAccountReregisterTimeoutDefault = 300;
return self;
}
- (void)dealloc {
NSLog(@"Releasing SIP Account");
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self logout];
if (calls!=nil)
[calls release];
if (fullName!=nil)
@ -180,10 +180,10 @@ const int MGMSIPAccountReregisterTimeoutDefault = 300;
else
reregisterTimeout = theReregisterTimeout;
}
- (int)identifier {
- (pjsua_acc_id)identifier {
return identifier;
}
- (void)setIdentifier:(int)theIdentifier {
- (void)setIdentifier:(pjsua_acc_id)theIdentifier {
identifier = theIdentifier;
}
- (NSString *)password {
@ -355,7 +355,11 @@ const int MGMSIPAccountReregisterTimeoutDefault = 300;
return call;
}
- (MGMSIPCall *)makeCallToNumber:(NSString *)theNumber {
MGMSIPURL *SIPURL = [MGMSIPURL URLWithFullName:nil userName:theNumber host:domain];
MGMSIPURL *SIPURL = [MGMSIPURL URLWithSIPAddress:theNumber];
if ([[SIPURL host] isEqual:theNumber]) {
[SIPURL setHost:domain];
[SIPURL setUserName:theNumber];
}
return [self makeCallToSIPURL:SIPURL];
}
- (MGMSIPCall *)makeCallToSIPURL:(MGMSIPURL *)theURL {

View File

@ -44,7 +44,7 @@ typedef enum {
@interface MGMSIPCall : NSObject {
id<MGMSIPCallDelegate> delegate;
MGMSIPAccount *account;
int identifier;
pjsua_call_id identifier;
MGMSIPURL *remoteURL;
MGMSIPURL *localURL;
@ -57,6 +57,7 @@ typedef enum {
BOOL incoming;
BOOL muted;
BOOL micMuted;
BOOL speaker;
NSString *holdMusicPath;
BOOL onHold;
pjsua_player_id holdMusicPlayer;
@ -72,8 +73,8 @@ typedef enum {
- (id<MGMSIPCallDelegate>)delegate;
- (void)setDelegate:(id)theDelegate;
- (MGMSIPAccount *)account;
- (int)identifier;
- (void)setIdentifier:(int)theIdentifier;
- (pjsua_call_id)identifier;
- (void)setIdentifier:(pjsua_call_id)theIdentifier;
- (MGMSIPURL *)remoteURL;
- (MGMSIPURL *)localURL;
@ -126,5 +127,10 @@ typedef enum {
- (void)mute;
- (BOOL)isMicMuted;
- (void)muteMic;
#if TARGET_OS_IPHONE
- (BOOL)isOnSpeaker;
- (void)speaker;
#endif
@end
#endif

View File

@ -12,9 +12,10 @@
#import "MGMSIPURL.h"
#import "MGMSIP.h"
#import "MGMAddons.h"
#import <AudioToolbox/AudioToolbox.h>
@implementation MGMSIPCall
- (id)initWithIdentifier:(int)theIdentifier account:(MGMSIPAccount *)theAccount {
- (id)initWithIdentifier:(pjsua_call_id)theIdentifier account:(MGMSIPAccount *)theAccount {
if (self = [super init]) {
account = theAccount;
identifier = theIdentifier;
@ -40,19 +41,8 @@
incoming = (state==MGMSIPCallIncomingState);
muted = NO;
pjsua_media_config mediaConfig = [[MGMSIP sharedSIP] mediaConfig];
unsigned int samplesPerFrame = mediaConfig.audio_frame_ptime * mediaConfig.clock_rate * mediaConfig.channel_count / 1000;
pj_status_t status = pjmedia_tonegen_create([[MGMSIP sharedSIP] PJPool], mediaConfig.clock_rate, mediaConfig.channel_count, samplesPerFrame, 16, 0, &toneGenPort);
if (status!=PJ_SUCCESS) {
NSLog(@"Error creating tone generator");
} else {
status = pjsua_conf_add_port([[MGMSIP sharedSIP] PJPool], toneGenPort, &toneGenSlot);
if (status!=PJ_SUCCESS)
NSLog(@"Error adding tone generator");
else
pjsua_conf_connect(toneGenSlot, 0);
}
speaker = NO;
toneGenSlot = PJSUA_INVALID_ID;
}
bzero(&PJThreadDesc, sizeof(pj_thread_desc));
}
@ -74,7 +64,7 @@
[transferStatusText release];
if (holdMusicPath!=nil)
[holdMusicPath release];
if (toneGenPort!=NULL) {
if (toneGenSlot!=PJSUA_INVALID_ID) {
pjsua_conf_remove_port(toneGenSlot);
pjmedia_port_destroy(toneGenPort);
toneGenPort = NULL;
@ -95,10 +85,10 @@
- (MGMSIPAccount *)account {
return account;
}
- (int)identifier {
- (pjsua_call_id)identifier {
return identifier;
}
- (void)setIdentifier:(int)theIdentifier {
- (void)setIdentifier:(pjsua_call_id)theIdentifier {
identifier = theIdentifier;
}
@ -114,6 +104,11 @@
}
- (void)setState:(MGMSIPCallState)theState {
if (theState==MGMSIPCallDisconnectedState) {
#if TARGET_OS_IPHONE
if (speaker) [self speaker];
#endif
if (isRingbackOn)
[self stopRingback];
if (holdMusicPlayer!=PJSUA_INVALID_ID)
[self performSelectorOnMainThread:@selector(stopHoldMusic) withObject:nil waitUntilDone:NO];
if (recorderID!=PJSUA_INVALID_ID)
@ -296,7 +291,7 @@
}
- (void)startRingback {
if (identifier==PJSUA_INVALID_ID || state==MGMSIPCallDisconnectedState)
if (identifier==PJSUA_INVALID_ID)
return;
if (isRingbackOn)
@ -312,7 +307,7 @@
bzero(&PJThreadDesc, sizeof(pj_thread_desc));
}
- (void)stopRingback {
if (identifier==PJSUA_INVALID_ID || state==MGMSIPCallDisconnectedState)
if (identifier==PJSUA_INVALID_ID)
return;
if (!isRingbackOn)
@ -323,7 +318,7 @@
[[MGMSIP sharedSIP] registerThread:&PJThreadDesc];
int ringbackCount = [[MGMSIP sharedSIP] ringbackCount];
if (ringbackCount<0) return;
if (ringbackCount<=0) return;
[[MGMSIP sharedSIP] setRingbackCount:ringbackCount-1];
if ([[MGMSIP sharedSIP] ringbackSlot]!=PJSUA_INVALID_ID) {
pjsua_conf_disconnect([[MGMSIP sharedSIP] ringbackSlot], 0);
@ -356,6 +351,21 @@
sendSuccessful = (status==PJ_SUCCESS);
}
}
if (toneGenSlot==PJSUA_INVALID_ID) {
pjsua_media_config mediaConfig = [[MGMSIP sharedSIP] mediaConfig];
unsigned int samplesPerFrame = mediaConfig.audio_frame_ptime * mediaConfig.clock_rate * mediaConfig.channel_count / 1000;
pj_status_t status = pjmedia_tonegen_create([[MGMSIP sharedSIP] PJPool], mediaConfig.clock_rate, mediaConfig.channel_count, samplesPerFrame, 16, 0, &toneGenPort);
if (status!=PJ_SUCCESS) {
NSLog(@"Error creating tone generator");
} else {
status = pjsua_conf_add_port([[MGMSIP sharedSIP] PJPool], toneGenPort, &toneGenSlot);
if (status!=PJ_SUCCESS)
NSLog(@"Error adding tone generator");
else
pjsua_conf_connect(toneGenSlot, 0);
}
}
if (!sendSuccessful)
pjsua_conf_connect(toneGenSlot, pjsua_call_get_conf_port(identifier));
for (unsigned int i=0; i<[theDigits length]; i++) {
@ -520,5 +530,17 @@
micMuted = !micMuted;
bzero(&PJThreadDesc, sizeof(pj_thread_desc));
}
#if TARGET_OS_IPHONE
- (BOOL)isOnSpeaker {
return speaker;
}
- (void)speaker {
speaker = !speaker;
UInt32 route = (speaker ? kAudioSessionOverrideAudioRoute_Speaker : kAudioSessionOverrideAudioRoute_None);
if (AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(route), &route)!=noErr)
speaker = !speaker;
}
#endif
@end
#endif

View File

@ -380,7 +380,7 @@ NSString * const MGMSID = @"id";
int type = [[data objectForKey:MGMIType] intValue];
if (type==MGMIVoicemailType) {
return [data objectForKey:MGMIText];
} else if (type==MGMISMSIn || type==MGMISMSOut) {
} else if (type==MGMISMSInType || type==MGMISMSOutType) {
return [[[[data objectForKey:MGMIMessages] lastObject] objectForKey:MGMIText] flattenHTML];
} else {
return [[[data objectForKey:MGMIPhoneNumber] areaCode] areaCodeLocation];
@ -425,7 +425,7 @@ NSString * const MGMSID = @"id";
rowRect.origin.x += ((rowRect.size.width-[playWindow frame].size.width)/2);
[playWindow setFrameOrigin:rowRect.origin];
[playWindow makeKeyAndOrderFront:self];
} else if (type==MGMISMSIn || type==MGMISMSOut) {
} else if (type==MGMISMSInType || type==MGMISMSOutType) {
[[[(MGMVoiceUser *)[instance delegate] controller] SMSManager] messageWithData:data instance:instance];
} else {
[(MGMVoiceUser *)[instance delegate] runAction:sender];

View File

@ -437,6 +437,9 @@ NSString * const MGMSIPDefaultDomain = @"proxy01.sipphone.com";
return [S7CheckUser password];
}
- (void)registrationChanged {
[self performSelector:@selector(S7RegistrationChanged) withObject:nil afterDelay:0.5];
}
- (void)S7RegistrationChanged {
#if MGMSIPENABLED
if (S7SIPRegistrationTimeout!=nil) {
[S7SIPRegistrationTimeout invalidate];

View File

@ -76,7 +76,7 @@ NSString * const MGMSCTitleNoNameFormat = @"Call With %@";
[incomingWindow makeKeyAndOrderFront:self];
[call sendRingingNotification];
NSString *ringtonePath = [[[SIPUser controller] themeManager] currentSoundPath:MGMTSSIPRingtone];
if (![ringtonePath isEqual:MGMTNoSound]) {
if (ringtonePath!=nil && ![ringtonePath isEqual:MGMTNoSound]) {
ringtone = [[MGMSound alloc] initWithContentsOfFile:ringtonePath];
[ringtone setLoops:YES];
[ringtone play];
@ -103,6 +103,14 @@ NSString * const MGMSCTitleNoNameFormat = @"Call With %@";
[callWindow makeKeyAndOrderFront:self];
}
if ([call state]==MGMSIPCallDisconnectedState) {
if (ringtone!=nil) {
[ringtone stop];
[ringtone release];
ringtone = nil;
}
}
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:@selector(soundChanged:) name:MGMTSoundChangedNotification object:nil];
[notificationCenter addObserver:self selector:@selector(volumeChanged:) name:MGMSIPVolumeChangedNotification object:nil];

View File

@ -67,6 +67,14 @@ NSString * const MGMSIPUserAreaCode = @"MGMVSIPUserAreaCode";
[progressFadeAnimation release];
progressFadeAnimation = nil;
}
if (progressView!=nil) {
[progressView stopProgess];
[progressView release];
}
if (SIPRegistrationTimeout!=nil) {
[SIPRegistrationTimeout invalidate];
[SIPRegistrationTimeout release];
}
[super dealloc];
if (calls!=nil) {
[calls removeAllObjects];
@ -218,6 +226,19 @@ NSString * const MGMSIPUserAreaCode = @"MGMVSIPUserAreaCode";
- (IBAction)runAction:(id)sender {
[self call:sender];
}
- (NSString *)currentPhoneNumber {
NSString *phoneNumber = nil;
if (phoneNumber==nil && ![[phoneField stringValue] isPhoneComplete]) {
if ([contactViews count]>0) {
[self selectFirstContact];
} else {
return [phoneField stringValue];
}
}
if (phoneNumber==nil)
phoneNumber = [[phoneField stringValue] phoneFormatWithAreaCode:[self areaCode]];
return phoneNumber;
}
- (IBAction)call:(id)sender {
NSString *phoneNumber = [controller currentPhoneNumber];
if (phoneNumber==nil || [phoneNumber isEqual:@""]) {

View File

@ -3,7 +3,7 @@ To get the latest source to PJProject, run the command below.
svn checkout http://svn.pjsip.org/repos/pjproject/trunk pjproject
To get the revision that I am using in VoiceMac and VoiceMob, run the command below.
svn checkout -r 3334 http://svn.pjsip.org/repos/pjproject/trunk pjproject
svn checkout -r 3346 http://svn.pjsip.org/repos/pjproject/trunk pjproject
Building.
To build for VoiceMac, run the command below.

View File

@ -523,6 +523,7 @@
isa = PBXProject;
buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "VoiceBase" */;
compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
@ -874,14 +875,17 @@
"$(inherited)",
"\"$(SRCROOT)/Libraries/lib\"",
);
OTHER_CFLAGS = "-fblocks";
OTHER_CFLAGS = (
"-D__IPHONE_OS_VERSION_MIN_REQUIRED=030000",
"-fblocks",
);
OTHER_LDFLAGS = (
"-ObjC",
"-all_load",
);
PREBINDING = NO;
PRODUCT_NAME = VoiceBase;
SDKROOT = iphoneos4.0;
SDKROOT = iphoneos4.1;
};
name = Debug;
};
@ -901,6 +905,7 @@
"\"$(SRCROOT)/Libraries/lib\"",
);
OTHER_CFLAGS = (
"-D__IPHONE_OS_VERSION_MIN_REQUIRED=030000",
"-fblocks",
"-DPJ_AUTOCONF=1",
"-DNDEBUG",
@ -929,7 +934,7 @@
);
PREBINDING = NO;
PRODUCT_NAME = VoiceBase;
SDKROOT = iphoneos4.0;
SDKROOT = iphoneos4.1;
};
name = "Debug SIP";
};
@ -951,14 +956,17 @@
"$(inherited)",
"\"$(SRCROOT)/Libraries/lib\"",
);
OTHER_CFLAGS = "-fblocks";
OTHER_CFLAGS = (
"-D__IPHONE_OS_VERSION_MIN_REQUIRED=030000",
"-fblocks",
);
OTHER_LDFLAGS = (
"-ObjC",
"-all_load",
);
PREBINDING = NO;
PRODUCT_NAME = VoiceBase;
SDKROOT = iphoneos4.0;
SDKROOT = iphoneos4.1;
ZERO_LINK = NO;
};
name = Release;
@ -979,6 +987,7 @@
"\"$(SRCROOT)/Libraries/lib\"",
);
OTHER_CFLAGS = (
"-D__IPHONE_OS_VERSION_MIN_REQUIRED=030000",
"-fblocks",
"-DPJ_AUTOCONF=1",
"-DNDEBUG",
@ -1009,7 +1018,7 @@
PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/VoiceBase;
PRODUCT_NAME = VoiceBase;
PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/VoiceBase;
SDKROOT = iphoneos4.0;
SDKROOT = iphoneos4.1;
};
name = "Release SIP";
};

View File

@ -633,6 +633,7 @@
isa = PBXProject;
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "VoiceMac" */;
compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,