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:
parent
a644448ef9
commit
f7a808f394
@ -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];
|
||||
}
|
||||
if ([theNumber isPhone])
|
||||
return [theNumber readableNumber];
|
||||
return theNumber;
|
||||
}
|
||||
|
||||
- (NSArray *)groups {
|
||||
|
@ -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;
|
||||
|
@ -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++) {
|
||||
|
@ -42,6 +42,7 @@
|
||||
}
|
||||
- (void)dealloc {
|
||||
if (sound!=nil) {
|
||||
[sound setDelegate:nil];
|
||||
[sound stop];
|
||||
[sound release];
|
||||
}
|
||||
|
@ -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%";
|
||||
|
@ -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
|
@ -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,6 +528,7 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
|
||||
[pool drain];
|
||||
return;
|
||||
}
|
||||
pjsua_acc_add_local(UDPTransport, PJ_TRUE, &UDPAccount);
|
||||
if (port==0) {
|
||||
pjsua_transport_info transportInfo;
|
||||
status = pjsua_transport_get_info(UDPTransport, &transportInfo);
|
||||
@ -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;
|
||||
@ -714,6 +761,9 @@ 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) {
|
||||
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];
|
||||
@ -723,6 +773,7 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
|
||||
[pool drain];
|
||||
return;
|
||||
}
|
||||
}
|
||||
[theAccount setIdentifier:identifier];
|
||||
[theAccount setOnline:YES];
|
||||
bzero(&PJThreadDesc, sizeof(pj_thread_desc));
|
||||
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
@ -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
|
@ -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];
|
||||
|
@ -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];
|
||||
|
@ -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];
|
||||
|
@ -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:@""]) {
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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.
|
||||
|
@ -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";
|
||||
};
|
||||
|
@ -633,6 +633,7 @@
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "VoiceMac" */;
|
||||
compatibilityVersion = "Xcode 3.1";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 1;
|
||||
knownRegions = (
|
||||
en,
|
||||
|
Loading…
Reference in New Issue
Block a user