├── .doxygen ├── .gitignore ├── .gitmodules ├── Default-568h@2x.png ├── DoxygenLayout.xml ├── Gossip.xcodeproj └── project.pbxproj ├── Gossip ├── GSAccount+Private.h ├── GSAccount.h ├── GSAccount.m ├── GSAccountConfiguration.h ├── GSAccountConfiguration.m ├── GSCall+Private.h ├── GSCall.h ├── GSCall.m ├── GSCodecInfo+Private.h ├── GSCodecInfo.h ├── GSCodecInfo.m ├── GSConfiguration.h ├── GSConfiguration.m ├── GSDispatch.h ├── GSDispatch.m ├── GSIncomingCall.h ├── GSIncomingCall.m ├── GSNotifications.h ├── GSNotifications.m ├── GSOutgoingCall.h ├── GSOutgoingCall.m ├── GSPJUtil.h ├── GSPJUtil.m ├── GSRingback.h ├── GSRingback.m ├── GSUserAgent+Private.h ├── GSUserAgent.h ├── GSUserAgent.m ├── Gossip.h ├── PJSIP.h └── Util.h ├── GossipExample ├── GSEAppDelegate.h ├── GSEAppDelegate.m ├── GSECallInitController.h ├── GSECallInitController.m ├── GSECallViewController.h ├── GSECallViewController.m ├── GSECallViewController.xib ├── GSECodecsViewController.h ├── GSECodecsViewController.m ├── GSEConfigurationViewController.h ├── GSEConfigurationViewController.m ├── GSEMenuViewController.h ├── GSEMenuViewController.m ├── GSEMenuViewController.xib ├── GSERootViewController.h ├── GSERootViewController.m ├── GossipExample-Info.plist ├── GossipExample-Prefix.pch ├── en.lproj │ └── InfoPlist.strings ├── main.m └── ringtone.wav ├── LICENSE.md ├── README.md ├── gen-docs ├── gossip.podspec └── pjsip ├── .gitignore ├── config_site.h ├── lib ├── arm64 │ ├── libg7221codec-arm-apple-darwin9.a │ ├── libgsmcodec-arm-apple-darwin9.a │ ├── libilbccodec-arm-apple-darwin9.a │ ├── libpj-arm-apple-darwin9.a │ ├── libpjlib-util-arm-apple-darwin9.a │ ├── libpjmedia-arm-apple-darwin9.a │ ├── libpjmedia-audiodev-arm-apple-darwin9.a │ ├── libpjmedia-codec-arm-apple-darwin9.a │ ├── libpjmedia-videodev-arm-apple-darwin9.a │ ├── libpjnath-arm-apple-darwin9.a │ ├── libpjsdp-arm-apple-darwin9.a │ ├── libpjsip-arm-apple-darwin9.a │ ├── libpjsip-simple-arm-apple-darwin9.a │ ├── libpjsip-ua-arm-apple-darwin9.a │ ├── libpjsua-arm-apple-darwin9.a │ ├── libpjsua2-arm-apple-darwin9.a │ ├── libresample-arm-apple-darwin9.a │ ├── libspeex-arm-apple-darwin9.a │ └── libsrtp-arm-apple-darwin9.a ├── armv6 │ ├── libg7221codec-arm-apple-darwin9.a │ ├── libgsmcodec-arm-apple-darwin9.a │ ├── libilbccodec-arm-apple-darwin9.a │ ├── libpj-arm-apple-darwin9.a │ ├── libpjlib-util-arm-apple-darwin9.a │ ├── libpjmedia-arm-apple-darwin9.a │ ├── libpjmedia-audiodev-arm-apple-darwin9.a │ ├── libpjmedia-codec-arm-apple-darwin9.a │ ├── libpjmedia-videodev-arm-apple-darwin9.a │ ├── libpjnath-arm-apple-darwin9.a │ ├── libpjsdp-arm-apple-darwin9.a │ ├── libpjsip-arm-apple-darwin9.a │ ├── libpjsip-simple-arm-apple-darwin9.a │ ├── libpjsip-ua-arm-apple-darwin9.a │ ├── libpjsua-arm-apple-darwin9.a │ ├── libpjsua2-arm-apple-darwin9.a │ ├── libresample-arm-apple-darwin9.a │ ├── libspeex-arm-apple-darwin9.a │ └── libsrtp-arm-apple-darwin9.a ├── armv7 │ ├── libg7221codec-arm-apple-darwin9.a │ ├── libgsmcodec-arm-apple-darwin9.a │ ├── libilbccodec-arm-apple-darwin9.a │ ├── libpj-arm-apple-darwin9.a │ ├── libpjlib-util-arm-apple-darwin9.a │ ├── libpjmedia-arm-apple-darwin9.a │ ├── libpjmedia-audiodev-arm-apple-darwin9.a │ ├── libpjmedia-codec-arm-apple-darwin9.a │ ├── libpjmedia-videodev-arm-apple-darwin9.a │ ├── libpjnath-arm-apple-darwin9.a │ ├── libpjsdp-arm-apple-darwin9.a │ ├── libpjsip-arm-apple-darwin9.a │ ├── libpjsip-simple-arm-apple-darwin9.a │ ├── libpjsip-ua-arm-apple-darwin9.a │ ├── libpjsua-arm-apple-darwin9.a │ ├── libpjsua2-arm-apple-darwin9.a │ ├── libresample-arm-apple-darwin9.a │ ├── libspeex-arm-apple-darwin9.a │ └── libsrtp-arm-apple-darwin9.a ├── armv7s │ ├── libg7221codec-arm-apple-darwin9.a │ ├── libgsmcodec-arm-apple-darwin9.a │ ├── libilbccodec-arm-apple-darwin9.a │ ├── libpj-arm-apple-darwin9.a │ ├── libpjlib-util-arm-apple-darwin9.a │ ├── libpjmedia-arm-apple-darwin9.a │ ├── libpjmedia-audiodev-arm-apple-darwin9.a │ ├── libpjmedia-codec-arm-apple-darwin9.a │ ├── libpjmedia-videodev-arm-apple-darwin9.a │ ├── libpjnath-arm-apple-darwin9.a │ ├── libpjsdp-arm-apple-darwin9.a │ ├── libpjsip-arm-apple-darwin9.a │ ├── libpjsip-simple-arm-apple-darwin9.a │ ├── libpjsip-ua-arm-apple-darwin9.a │ ├── libpjsua-arm-apple-darwin9.a │ ├── libpjsua2-arm-apple-darwin9.a │ ├── libresample-arm-apple-darwin9.a │ ├── libspeex-arm-apple-darwin9.a │ └── libsrtp-arm-apple-darwin9.a ├── i386 │ ├── libg7221codec-arm-apple-darwin9.a │ ├── libgsmcodec-arm-apple-darwin9.a │ ├── libilbccodec-arm-apple-darwin9.a │ ├── libpj-arm-apple-darwin9.a │ ├── libpjlib-util-arm-apple-darwin9.a │ ├── libpjmedia-arm-apple-darwin9.a │ ├── libpjmedia-audiodev-arm-apple-darwin9.a │ ├── libpjmedia-codec-arm-apple-darwin9.a │ ├── libpjmedia-videodev-arm-apple-darwin9.a │ ├── libpjnath-arm-apple-darwin9.a │ ├── libpjsdp-arm-apple-darwin9.a │ ├── libpjsip-arm-apple-darwin9.a │ ├── libpjsip-simple-arm-apple-darwin9.a │ ├── libpjsip-ua-arm-apple-darwin9.a │ ├── libpjsua-arm-apple-darwin9.a │ ├── libpjsua2-arm-apple-darwin9.a │ ├── libresample-arm-apple-darwin9.a │ ├── libspeex-arm-apple-darwin9.a │ └── libsrtp-arm-apple-darwin9.a ├── libg7221codec-arm-apple-darwin9.a ├── libgsmcodec-arm-apple-darwin9.a ├── libilbccodec-arm-apple-darwin9.a ├── libpj-arm-apple-darwin9.a ├── libpjlib-util-arm-apple-darwin9.a ├── libpjmedia-arm-apple-darwin9.a ├── libpjmedia-audiodev-arm-apple-darwin9.a ├── libpjmedia-codec-arm-apple-darwin9.a ├── libpjmedia-videodev-arm-apple-darwin9.a ├── libpjnath-arm-apple-darwin9.a ├── libpjsdp-arm-apple-darwin9.a ├── libpjsip-arm-apple-darwin9.a ├── libpjsip-simple-arm-apple-darwin9.a ├── libpjsip-ua-arm-apple-darwin9.a ├── libpjsua-arm-apple-darwin9.a ├── libpjsua2-arm-apple-darwin9.a ├── libresample-arm-apple-darwin9.a ├── libspeex-arm-apple-darwin9.a └── libsrtp-arm-apple-darwin9.a └── pjsip /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | build/* 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | *.xcworkspace 12 | !default.xcworkspace 13 | xcuserdata 14 | profile 15 | *.moved-aside 16 | 17 | # CocoaPods stuff 18 | .ruby-version 19 | 20 | # Exclude OS X folder attributes 21 | .DS_Store 22 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "docs"] 2 | path = docs 3 | url = git://github.com/chakrit/gossip.git 4 | [submodule "pjsip/src"] 5 | path = pjsip/src 6 | url = git://github.com/chakrit/pjsip.git 7 | -------------------------------------------------------------------------------- /Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/Default-568h@2x.png -------------------------------------------------------------------------------- /DoxygenLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /Gossip/GSAccount+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSAccount+Private.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 8/20/12. 6 | // 7 | // 8 | 9 | #import "GSAccount.h" 10 | #import "GSAccountConfiguration.h" 11 | 12 | 13 | @interface GSAccount (Private) 14 | 15 | @property (nonatomic, readonly, copy) GSAccountConfiguration *configuration; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Gossip/GSAccount.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSAccount.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import 9 | #import "GSAccountConfiguration.h" 10 | @class GSAccount, GSCall; 11 | 12 | 13 | /// Account Status enum. 14 | typedef enum { 15 | GSAccountStatusOffline, ///< Account is offline or no registration has been done. 16 | GSAccountStatusInvalid, ///< Gossip has attempted registration but the credentials were invalid. 17 | GSAccountStatusConnecting, ///< Gossip is trying to register the account with the SIP server. 18 | GSAccountStatusConnected, ///< Account has been successfully registered with the SIP server. 19 | GSAccountStatusDisconnecting, ///< Account is being unregistered from the SIP server. 20 | } GSAccountStatus; ///< Account status enum. 21 | 22 | 23 | /// Delegate to receive account activity. 24 | @protocol GSAccountDelegate 25 | 26 | /// Called when an account recieves an incoming call. 27 | /** Call GSCall::begin to accept incoming call or GSCall::end to deny. 28 | * This should be done in a timely fashion since we do not support timeouts for incoming call yet. */ 29 | - (void)account:(GSAccount *)account didReceiveIncomingCall:(GSCall *)call; 30 | 31 | @end 32 | 33 | 34 | /// Represents a single PJSIP account. Only one account per session is supported right now. 35 | @interface GSAccount : NSObject 36 | 37 | @property (nonatomic, readonly) int accountId; ///< Account Id, automatically assigned by PJSIP. 38 | @property (nonatomic, readonly) GSAccountStatus status; ///< Account registration status. Supports KVO notification. 39 | 40 | @property (nonatomic, unsafe_unretained) id delegate; ///< Account activity delegate. 41 | 42 | /// Configures account with the specified configuration. 43 | /** Must be run once and only once before using the GSAccount instance. 44 | * Usually this is called automatically by the GSUserAgent instance. */ 45 | - (BOOL)configure:(GSAccountConfiguration *)configuration; 46 | 47 | - (BOOL)connect; ///< Connects and begin registering with the configured SIP registration server. 48 | - (BOOL)disconnect; ///< Unregister from the SIP registration server and disconnects. 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Gossip/GSAccount.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSAccount.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import "GSAccount.h" 9 | #import "GSAccount+Private.h" 10 | #import "GSCall.h" 11 | #import "GSDispatch.h" 12 | #import "GSUserAgent.h" 13 | #import "PJSIP.h" 14 | #import "Util.h" 15 | 16 | 17 | @implementation GSAccount { 18 | GSAccountConfiguration *_config; 19 | } 20 | 21 | - (id)init { 22 | if (self = [super init]) { 23 | _accountId = PJSUA_INVALID_ID; 24 | _status = GSAccountStatusOffline; 25 | _config = nil; 26 | 27 | _delegate = nil; 28 | 29 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 30 | [center addObserver:self 31 | selector:@selector(didReceiveIncomingCall:) 32 | name:GSSIPIncomingCallNotification 33 | object:[GSDispatch class]]; 34 | [center addObserver:self 35 | selector:@selector(registrationDidStart:) 36 | name:GSSIPRegistrationDidStartNotification 37 | object:[GSDispatch class]]; 38 | [center addObserver:self 39 | selector:@selector(registrationStateDidChange:) 40 | name:GSSIPRegistrationStateDidChangeNotification 41 | object:[GSDispatch class]]; 42 | } 43 | return self; 44 | } 45 | 46 | - (void)dealloc { 47 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 48 | [center removeObserver:self]; 49 | 50 | GSUserAgent *agent = [GSUserAgent sharedAgent]; 51 | if (_accountId != PJSUA_INVALID_ID && [agent status] != GSUserAgentStateDestroyed) { 52 | GSLogIfFails(pjsua_acc_del(_accountId)); 53 | _accountId = PJSUA_INVALID_ID; 54 | } 55 | 56 | _accountId = PJSUA_INVALID_ID; 57 | _config = nil; 58 | } 59 | 60 | 61 | - (GSAccountConfiguration *)configuration { 62 | return _config; 63 | } 64 | 65 | 66 | - (BOOL)configure:(GSAccountConfiguration *)configuration { 67 | _config = [configuration copy]; 68 | 69 | // prepare account config 70 | pjsua_acc_config accConfig; 71 | pjsua_acc_config_default(&accConfig); 72 | 73 | accConfig.id = [GSPJUtil PJAddressWithString:_config.address]; 74 | accConfig.reg_uri = [GSPJUtil PJAddressWithString:_config.domain]; 75 | accConfig.register_on_acc_add = PJ_FALSE; // connect manually 76 | accConfig.publish_enabled = _config.enableStatusPublishing ? PJ_TRUE : PJ_FALSE; 77 | 78 | if (!_config.proxyServer) { 79 | accConfig.proxy_cnt = 0; 80 | } else { 81 | accConfig.proxy_cnt = 1; 82 | accConfig.proxy[0] = [GSPJUtil PJAddressWithString:_config.proxyServer]; 83 | } 84 | 85 | // adds credentials info 86 | pjsip_cred_info creds; 87 | creds.scheme = [GSPJUtil PJStringWithString:_config.authScheme]; 88 | creds.realm = [GSPJUtil PJStringWithString:_config.authRealm]; 89 | creds.username = [GSPJUtil PJStringWithString:_config.username]; 90 | creds.data = [GSPJUtil PJStringWithString:_config.password]; 91 | creds.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD; 92 | 93 | accConfig.cred_count = 1; 94 | accConfig.cred_info[0] = creds; 95 | 96 | // finish 97 | GSReturnNoIfFails(pjsua_acc_add(&accConfig, PJ_TRUE, &_accountId)); 98 | return YES; 99 | } 100 | 101 | 102 | - (BOOL)connect { 103 | NSAssert(!!_config, @"GSAccount not configured."); 104 | 105 | GSReturnNoIfFails(pjsua_acc_set_registration(_accountId, PJ_TRUE)); 106 | GSReturnNoIfFails(pjsua_acc_set_online_status(_accountId, PJ_TRUE)); 107 | return YES; 108 | } 109 | 110 | - (BOOL)disconnect { 111 | NSAssert(!!_config, @"GSAccount not configured."); 112 | 113 | GSReturnNoIfFails(pjsua_acc_set_online_status(_accountId, PJ_FALSE)); 114 | GSReturnNoIfFails(pjsua_acc_set_registration(_accountId, PJ_FALSE)); 115 | return YES; 116 | } 117 | 118 | 119 | - (void)setStatus:(GSAccountStatus)newStatus { 120 | if (_status == newStatus) // don't send KVO notices unless it really changes. 121 | return; 122 | 123 | _status = newStatus; 124 | } 125 | 126 | 127 | - (void)didReceiveIncomingCall:(NSNotification *)notif { 128 | pjsua_acc_id accountId = GSNotifGetInt(notif, GSSIPAccountIdKey); 129 | pjsua_call_id callId = GSNotifGetInt(notif, GSSIPCallIdKey); 130 | if (accountId == PJSUA_INVALID_ID || accountId != _accountId) 131 | return; 132 | 133 | __block GSAccount *self_ = self; 134 | __block id delegate_ = _delegate; 135 | dispatch_async(dispatch_get_main_queue(), ^{ 136 | GSCall *call = [GSCall incomingCallWithId:callId toAccount:self]; 137 | if (![delegate_ respondsToSelector:@selector(account:didReceiveIncomingCall:)]) 138 | return; // call is disposed/hungup on dealloc 139 | 140 | [delegate_ performSelector:@selector(account:didReceiveIncomingCall:) 141 | withObject:self_ 142 | withObject:call]; 143 | }); 144 | } 145 | 146 | - (void)registrationDidStart:(NSNotification *)notif { 147 | pjsua_acc_id accountId = GSNotifGetInt(notif, GSSIPAccountIdKey); 148 | pj_bool_t renew = GSNotifGetBool(notif, GSSIPRenewKey); 149 | if (accountId == PJSUA_INVALID_ID || accountId != _accountId) 150 | return; 151 | 152 | GSAccountStatus accStatus = 0; 153 | accStatus = renew ? GSAccountStatusConnecting : GSAccountStatusDisconnecting; 154 | 155 | __block id self_ = self; 156 | dispatch_async(dispatch_get_main_queue(), ^{ [self_ setStatus:accStatus]; }); 157 | } 158 | 159 | - (void)registrationStateDidChange:(NSNotification *)notif { 160 | pjsua_acc_id accountId = GSNotifGetInt(notif, GSSIPAccountIdKey); 161 | if (accountId == PJSUA_INVALID_ID || accountId != _accountId) 162 | return; 163 | 164 | GSAccountStatus accStatus; 165 | 166 | pjsua_acc_info info; 167 | GSReturnIfFails(pjsua_acc_get_info(accountId, &info)); 168 | 169 | if (info.reg_last_err != PJ_SUCCESS) { 170 | accStatus = GSAccountStatusInvalid; 171 | 172 | } else { 173 | pjsip_status_code code = info.status; 174 | if (code == 0 || (info.online_status == PJ_FALSE)) { 175 | accStatus = GSAccountStatusOffline; 176 | } else if (PJSIP_IS_STATUS_IN_CLASS(code, 100) || PJSIP_IS_STATUS_IN_CLASS(code, 300)) { 177 | accStatus = GSAccountStatusConnecting; 178 | } else if (PJSIP_IS_STATUS_IN_CLASS(code, 200)) { 179 | accStatus = GSAccountStatusConnected; 180 | } else { 181 | accStatus = GSAccountStatusInvalid; 182 | } 183 | } 184 | 185 | __block id self_ = self; 186 | dispatch_async(dispatch_get_main_queue(), ^{ [self_ setStatus:accStatus]; }); 187 | } 188 | 189 | @end 190 | -------------------------------------------------------------------------------- /Gossip/GSAccountConfiguration.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSAccountConfiguration.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import 9 | 10 | 11 | /// Account configuration. Only supports "digest" and plain-text password authentication atm. 12 | @interface GSAccountConfiguration : NSObject 13 | 14 | @property (nonatomic, copy) NSString *address; ///< SIP address. 15 | @property (nonatomic, copy) NSString *domain; ///< SIP domain. 16 | @property (nonatomic, copy) NSString *proxyServer; ///< SIP outbound proxy server. 17 | @property (nonatomic, copy) NSString *authScheme; ///< Authentication scheme. Defaults to "digest". 18 | @property (nonatomic, copy) NSString *authRealm; ///< Authentication realm. Defaults to "*". 19 | @property (nonatomic, copy) NSString *username; ///< SIP username. 20 | @property (nonatomic, copy) NSString *password; ///< SIP password. 21 | 22 | @property (nonatomic) BOOL enableStatusPublishing; ///< Enable online/status publishing for services that support them. 23 | 24 | @property (nonatomic) BOOL enableRingback; ///< Enable automatic ringback sounds. 25 | @property (nonatomic, copy) NSString *ringbackFilename; ///< Filename to play as ringback sounds. Defaults to "ringtone.wav" so you can just include it in your bundle and Gossip will pick it up. 26 | 27 | + (id)defaultConfiguration; ///< Creates a GSAccountConfiguration instance with default configuration values. 28 | + (id)configurationWithConfiguration:(GSAccountConfiguration *)configuration; ///< Copy constructor. 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Gossip/GSAccountConfiguration.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSAccountConfiguration.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import "GSAccountConfiguration.h" 9 | 10 | 11 | @implementation GSAccountConfiguration 12 | 13 | + (id)defaultConfiguration { 14 | return [[self alloc] init]; 15 | } 16 | 17 | + (id)configurationWithConfiguration:(GSAccountConfiguration *)configuration { 18 | return [configuration copy]; 19 | } 20 | 21 | 22 | - (id)init { 23 | if (!(self = [super init])) 24 | return nil; // super init failed. 25 | 26 | _address = nil; 27 | _domain = nil; 28 | _proxyServer = nil; 29 | _authScheme = @"digest"; 30 | _authRealm = @"*"; 31 | _username = nil; 32 | _password = nil; 33 | 34 | _enableRingback = YES; 35 | _ringbackFilename = @"ringtone.wav"; 36 | 37 | // can prevent registration for services which don't support it so NO by default. 38 | _enableStatusPublishing = NO; 39 | return self; 40 | } 41 | 42 | - (void)dealloc { 43 | _address = nil; 44 | _domain = nil; 45 | _proxyServer = nil; 46 | _authScheme = nil; 47 | _authRealm = nil; 48 | _username = nil; 49 | _password = nil; 50 | _ringbackFilename = nil; 51 | } 52 | 53 | 54 | - (id)copyWithZone:(NSZone *)zone { 55 | GSAccountConfiguration *replica = [GSAccountConfiguration defaultConfiguration]; 56 | 57 | replica.address = self.address; 58 | replica.domain = self.domain; 59 | replica.proxyServer = self.proxyServer; 60 | replica.authScheme = self.authScheme; 61 | replica.authRealm = self.authRealm; 62 | replica.username = self.username; 63 | replica.password = self.password; 64 | 65 | replica.enableStatusPublishing = self.enableStatusPublishing; 66 | 67 | replica.enableRingback = self.enableRingback; 68 | replica.ringbackFilename = self.ringbackFilename; 69 | return replica; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /Gossip/GSCall+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSCall+Private.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/12/12. 6 | // 7 | 8 | #import "GSCall.h" 9 | 10 | 11 | @interface GSCall (Private) 12 | 13 | // private setter for internal use 14 | - (void)setCallId:(int)callId; 15 | - (void)setStatus:(GSCallStatus)status; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Gossip/GSCall.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSCall.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/9/12. 6 | // 7 | 8 | #import 9 | #import "GSAccount.h" 10 | #import "GSRingback.h" 11 | 12 | 13 | /// Call session states. 14 | typedef enum { 15 | GSCallStatusReady, ///< Call is ready to be made/pickup. 16 | GSCallStatusCalling, ///< Call is ringing. 17 | GSCallStatusConnecting, ///< User or other party has pick up the call. 18 | GSCallStatusConnected, ///< Call has connected and sound is now coming through. 19 | GSCallStatusDisconnected, ///< Call has been disconnected (user hangup/other party hangup.) 20 | } GSCallStatus; 21 | 22 | 23 | // TODO: Video call support? 24 | /// Represents a single calling session (either incoming or outgoing.) 25 | @interface GSCall : NSObject 26 | 27 | @property (nonatomic, unsafe_unretained, readonly) GSAccount *account; ///< An account this call is being made from. 28 | @property (nonatomic, readonly) GSRingback *ringback; ///< Returns the current GSRingback instance used to play the call's ringback. 29 | 30 | @property (nonatomic, readonly) int callId; ///< Call id. Autogenerated from PJSIP. 31 | @property (nonatomic, readonly) GSCallStatus status; ///< Call status. Supports KVO notification. 32 | 33 | @property (nonatomic, readonly) float volume; ///< Call volume. Set to 0 to mute. 34 | @property (nonatomic, readonly) float micVolume; ///< Call microphone volume. i.e. the volume to transmit sound from the mic. Set to 0 to mute. 35 | 36 | /// Creats a new outgoing call to the specified remoteUri. 37 | /** Use begin() to begin calling. */ 38 | + (id)outgoingCallToUri:(NSString *)remoteUri fromAccount:(GSAccount *)account; 39 | 40 | /// Creates a new incoming call from the specified PJSIP call id. And associate it with the speicifed account. 41 | /** Do not call this method directly, implement GSAccountDelegate and listen to the 42 | * GSAccountDelegate::account:didReceiveIncomingCall: message instead. */ 43 | + (id)incomingCallWithId:(int)callId toAccount:(GSAccount *)account; 44 | 45 | /// Initialize a new call with the specified account. 46 | /** Do not initialize a GSCall instance directly, instead use one of the provided static methods. 47 | * This method is only inteded to be used by child classes. */ 48 | - (id)initWithAccount:(GSAccount *)account; 49 | 50 | - (BOOL)setVolume:(float)volume; ///< Sets the call volume. Returns YES if successful. 51 | - (BOOL)setMicVolume:(float)volume; ///< Sets the microphone volume. Returns YES if successful. 52 | 53 | - (BOOL)begin; ///< Begins calling for outgoing call or answer incoming call. 54 | - (BOOL)end; ///< Stop calling and/or hangup call. 55 | 56 | - (BOOL)sendDTMFDigits:(NSString *)digits; ///< Sends DTMF digits over the call. 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /Gossip/GSCall.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSCall.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/9/12. 6 | // 7 | 8 | #import "GSCall.h" 9 | #import "GSCall+Private.h" 10 | #import "GSAccount+Private.h" 11 | #import "GSDispatch.h" 12 | #import "GSIncomingCall.h" 13 | #import "GSOutgoingCall.h" 14 | #import "GSRingback.h" 15 | #import "GSUserAgent+Private.h" 16 | #import "PJSIP.h" 17 | #import "Util.h" 18 | 19 | 20 | @implementation GSCall { 21 | pjsua_call_id _callId; 22 | float _volume; 23 | float _micVolume; 24 | float _volumeScale; 25 | } 26 | 27 | + (id)outgoingCallToUri:(NSString *)remoteUri fromAccount:(GSAccount *)account { 28 | GSOutgoingCall *call = [GSOutgoingCall alloc]; 29 | call = [call initWithRemoteUri:remoteUri fromAccount:account]; 30 | 31 | return call; 32 | } 33 | 34 | + (id)incomingCallWithId:(int)callId toAccount:(GSAccount *)account { 35 | GSIncomingCall *call = [GSIncomingCall alloc]; 36 | call = [call initWithCallId:callId toAccount:account]; 37 | 38 | return call; 39 | } 40 | 41 | 42 | - (id)init { 43 | return [self initWithAccount:nil]; 44 | } 45 | 46 | - (id)initWithAccount:(GSAccount *)account { 47 | if (self = [super init]) { 48 | GSAccountConfiguration *config = account.configuration; 49 | 50 | _account = account; 51 | _status = GSCallStatusReady; 52 | _callId = PJSUA_INVALID_ID; 53 | 54 | _ringback = nil; 55 | if (config.enableRingback) { 56 | _ringback = [GSRingback ringbackWithSoundNamed:config.ringbackFilename]; 57 | } 58 | 59 | _volumeScale = [GSUserAgent sharedAgent].configuration.volumeScale; 60 | _volume = 1.0 / _volumeScale; 61 | _micVolume = 1.0 / _volumeScale; 62 | 63 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 64 | [center addObserver:self 65 | selector:@selector(callStateDidChange:) 66 | name:GSSIPCallStateDidChangeNotification 67 | object:[GSDispatch class]]; 68 | [center addObserver:self 69 | selector:@selector(callMediaStateDidChange:) 70 | name:GSSIPCallMediaStateDidChangeNotification 71 | object:[GSDispatch class]]; 72 | } 73 | return self; 74 | } 75 | 76 | - (void)dealloc { 77 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 78 | [center removeObserver:self]; 79 | 80 | if (_ringback && _ringback.isPlaying) { 81 | [_ringback stop]; 82 | _ringback = nil; 83 | } 84 | 85 | if (_callId != PJSUA_INVALID_ID && pjsua_call_is_active(_callId)) { 86 | GSLogIfFails(pjsua_call_hangup(_callId, 0, NULL, NULL)); 87 | } 88 | 89 | _account = nil; 90 | _callId = PJSUA_INVALID_ID; 91 | _ringback = nil; 92 | } 93 | 94 | 95 | - (int)callId { 96 | return _callId; 97 | } 98 | 99 | - (void)setCallId:(int)callId { 100 | [self willChangeValueForKey:@"callId"]; 101 | _callId = callId; 102 | [self didChangeValueForKey:@"callId"]; 103 | } 104 | 105 | - (void)setStatus:(GSCallStatus)status { 106 | [self willChangeValueForKey:@"status"]; 107 | _status = status; 108 | [self didChangeValueForKey:@"status"]; 109 | } 110 | 111 | 112 | - (float)volume { 113 | return _volume; 114 | } 115 | 116 | - (BOOL)setVolume:(float)volume { 117 | [self willChangeValueForKey:@"volume"]; 118 | BOOL result = [self adjustVolume:volume mic:_micVolume]; 119 | [self didChangeValueForKey:@"volume"]; 120 | 121 | return result; 122 | } 123 | 124 | - (float)micVolume { 125 | return _micVolume; 126 | } 127 | 128 | - (BOOL)setMicVolume:(float)micVolume { 129 | [self willChangeValueForKey:@"micVolume"]; 130 | BOOL result = [self adjustVolume:_volume mic:micVolume]; 131 | [self didChangeValueForKey:@"micVolume"]; 132 | 133 | return result; 134 | } 135 | 136 | 137 | - (BOOL)begin { 138 | // for child overrides only 139 | return NO; 140 | } 141 | 142 | - (BOOL)end { 143 | // for child overrides only 144 | return NO; 145 | } 146 | 147 | 148 | - (BOOL)sendDTMFDigits:(NSString *)digits { 149 | pj_str_t pjDigits = [GSPJUtil PJStringWithString:digits]; 150 | pjsua_call_dial_dtmf(_callId, &pjDigits); 151 | } 152 | 153 | 154 | - (void)startRingback { 155 | if (!_ringback || _ringback.isPlaying) 156 | return; 157 | 158 | [_ringback play]; 159 | } 160 | 161 | - (void)stopRingback { 162 | if (!(_ringback && _ringback.isPlaying)) 163 | return; 164 | 165 | [_ringback stop]; 166 | } 167 | 168 | 169 | - (void)callStateDidChange:(NSNotification *)notif { 170 | pjsua_call_id callId = GSNotifGetInt(notif, GSSIPCallIdKey); 171 | pjsua_acc_id accountId = GSNotifGetInt(notif, GSSIPAccountIdKey); 172 | if (callId != _callId || accountId != _account.accountId) 173 | return; 174 | 175 | pjsua_call_info callInfo; 176 | pjsua_call_get_info(_callId, &callInfo); 177 | 178 | GSCallStatus callStatus; 179 | switch (callInfo.state) { 180 | case PJSIP_INV_STATE_NULL: { 181 | callStatus = GSCallStatusReady; 182 | } break; 183 | 184 | case PJSIP_INV_STATE_CALLING: 185 | case PJSIP_INV_STATE_INCOMING: { 186 | callStatus = GSCallStatusCalling; 187 | } break; 188 | 189 | case PJSIP_INV_STATE_EARLY: 190 | case PJSIP_INV_STATE_CONNECTING: { 191 | [self startRingback]; 192 | callStatus = GSCallStatusConnecting; 193 | } break; 194 | 195 | case PJSIP_INV_STATE_CONFIRMED: { 196 | [self stopRingback]; 197 | callStatus = GSCallStatusConnected; 198 | } break; 199 | 200 | case PJSIP_INV_STATE_DISCONNECTED: { 201 | [self stopRingback]; 202 | callStatus = GSCallStatusDisconnected; 203 | } break; 204 | } 205 | 206 | __block id self_ = self; 207 | dispatch_async(dispatch_get_main_queue(), ^{ [self_ setStatus:callStatus]; }); 208 | } 209 | 210 | - (void)callMediaStateDidChange:(NSNotification *)notif { 211 | pjsua_call_id callId = GSNotifGetInt(notif, GSSIPCallIdKey); 212 | if (callId != _callId) 213 | return; 214 | 215 | pjsua_call_info callInfo; 216 | GSReturnIfFails(pjsua_call_get_info(_callId, &callInfo)); 217 | 218 | if (callInfo.media_status == PJSUA_CALL_MEDIA_ACTIVE) { 219 | pjsua_conf_port_id callPort = pjsua_call_get_conf_port(_callId); 220 | GSReturnIfFails(pjsua_conf_connect(callPort, 0)); 221 | GSReturnIfFails(pjsua_conf_connect(0, callPort)); 222 | 223 | [self adjustVolume:_volume mic:_micVolume]; 224 | } 225 | } 226 | 227 | 228 | - (BOOL)adjustVolume:(float)volume mic:(float)micVolume { 229 | GSAssert(0.0 <= volume && volume <= 1.0, @"Volume value must be between 0.0 and 1.0"); 230 | GSAssert(0.0 <= micVolume && micVolume <= 1.0, @"Mic Volume must be between 0.0 and 1.0"); 231 | 232 | _volume = volume; 233 | _micVolume = micVolume; 234 | if (_callId == PJSUA_INVALID_ID) 235 | return YES; 236 | 237 | pjsua_call_info callInfo; 238 | pjsua_call_get_info(_callId, &callInfo); 239 | if (callInfo.media_status == PJSUA_CALL_MEDIA_ACTIVE) { 240 | 241 | // scale volume as per configured volume scale 242 | volume *= _volumeScale; 243 | micVolume *= _volumeScale; 244 | pjsua_conf_port_id callPort = pjsua_call_get_conf_port(_callId); 245 | GSReturnNoIfFails(pjsua_conf_adjust_rx_level(callPort, volume)); 246 | GSReturnNoIfFails(pjsua_conf_adjust_tx_level(callPort, micVolume)); 247 | } 248 | 249 | // send volume change notification 250 | NSDictionary *info = nil; 251 | info = [NSDictionary dictionaryWithObjectsAndKeys: 252 | [NSNumber numberWithFloat:volume], GSVolumeKey, 253 | [NSNumber numberWithFloat:micVolume], GSMicVolumeKey, nil]; 254 | 255 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 256 | [center postNotificationName:GSVolumeDidChangeNotification 257 | object:self 258 | userInfo:info]; 259 | 260 | return YES; 261 | } 262 | 263 | @end 264 | -------------------------------------------------------------------------------- /Gossip/GSCodecInfo+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSCodecInfo+Private.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/13/12. 6 | // 7 | 8 | #import "GSCodecInfo.h" 9 | #import "PJSIP.h" 10 | 11 | 12 | @interface GSCodecInfo (Private) 13 | 14 | - (id)initWithCodecInfo:(pjsua_codec_info *)codecInfo; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Gossip/GSCodecInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSCodecInfo.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/13/12. 6 | // 7 | 8 | #import 9 | 10 | 11 | /// Contains information for a codec. 12 | @interface GSCodecInfo : NSObject 13 | 14 | @property (nonatomic, readonly) NSString *codecId; ///< Codec id as given by PJSIP 15 | @property (nonatomic, readonly) NSString *description; ///< Codec descrition as given by PJSIP 16 | @property (nonatomic, readonly) NSUInteger priority; ///< Codec priority in the range 1-254 or 0 to disable. 17 | 18 | - (BOOL)setPriority:(NSUInteger)newPriority; ///< Sets codec priority. 19 | - (BOOL)setMaxPriority; ///< Sets codec priority to maximum (254) 20 | 21 | - (BOOL)disable; ///< Disable the codec. (Sets priority to 0) 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Gossip/GSCodecInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSCodecInfo.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/13/12. 6 | // 7 | 8 | #import "GSCodecInfo.h" 9 | #import "GSCodecInfo+Private.h" 10 | #import "PJSIP.h" 11 | #import "Util.h" 12 | 13 | 14 | @implementation GSCodecInfo { 15 | pjsua_codec_info _info; 16 | } 17 | 18 | - (id)initWithCodecInfo:(pjsua_codec_info *)codecInfo { 19 | if (self = [super init]) { 20 | _info = *codecInfo; 21 | } 22 | return self; 23 | } 24 | 25 | 26 | - (NSString *)codecId { 27 | return [GSPJUtil stringWithPJString:&_info.codec_id]; 28 | } 29 | 30 | - (NSString *)description { 31 | return [GSPJUtil stringWithPJString:&_info.desc]; 32 | } 33 | 34 | - (NSUInteger)priority { 35 | return _info.priority; 36 | } 37 | 38 | - (BOOL)setPriority:(NSUInteger)newPriority { 39 | GSReturnNoIfFails(pjsua_codec_set_priority(&_info.codec_id, newPriority)); 40 | 41 | _info.priority = newPriority; // update cached info 42 | return YES; 43 | } 44 | 45 | - (BOOL)setMaxPriority { 46 | return [self setPriority:254]; 47 | } 48 | 49 | 50 | - (BOOL)disable { 51 | return [self setPriority:0]; // 0 disables the codec as said in pjsua online doc 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /Gossip/GSConfiguration.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSConfiguration.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import 9 | #import "GSAccountConfiguration.h" 10 | 11 | 12 | /// Supported transport types. 13 | typedef enum { 14 | GSUDPTransportType, ///< UDP transport type. 15 | GSUDP6TransportType, ///< UDP on IPv6 transport type. 16 | GSTCPTransportType, ///< TCP transport type. 17 | GSTCP6TransportType, ///< TCP on IPv6 transport type. 18 | } GSTransportType; 19 | 20 | 21 | /// Main class for configuring a SIP user agent. 22 | @interface GSConfiguration : NSObject 23 | 24 | @property (nonatomic) unsigned int logLevel; ///< PJSIP log level. 25 | @property (nonatomic) unsigned int consoleLogLevel; ///< PJSIP console output level. 26 | 27 | @property (nonatomic) GSTransportType transportType; ///< Transport type to use for connection. 28 | 29 | @property (nonatomic) unsigned int clockRate; ///< PJSIP clock rate. 30 | @property (nonatomic) unsigned int soundClockRate; ///< PJSIP sound clock rate. 31 | @property (nonatomic) float volumeScale; ///< Used for scaling volumes up and down. 32 | 33 | @property (nonatomic, strong) GSAccountConfiguration *account; 34 | 35 | + (id)defaultConfiguration; 36 | + (id)configurationWithConfiguration:(GSConfiguration *)configuration; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Gossip/GSConfiguration.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSConfiguration.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import "GSConfiguration.h" 9 | 10 | 11 | @implementation GSConfiguration 12 | 13 | + (id)defaultConfiguration { 14 | return [[GSConfiguration alloc] init]; 15 | } 16 | 17 | + (id)configurationWithConfiguration:(GSConfiguration *)configuration { 18 | return [configuration copy]; 19 | } 20 | 21 | 22 | - (id)init { 23 | if (!(self = [super init])) 24 | return nil; // init failed. 25 | 26 | // default values 27 | _logLevel = 2; 28 | _consoleLogLevel = 2; 29 | 30 | _transportType = GSUDPTransportType; 31 | 32 | // match clock rate to default number provided by PJSIP. 33 | // http://www.pjsip.org/pjsip/docs/html/structpjsua__media__config.htm#a24792c277d6c6c309eccda9047f641a5 34 | // setting sound clock rate to zero makes it use the conference bridge rate 35 | // http://www.pjsip.org/pjsip/docs/html/structpjsua__media__config.htm#aeb0fbbdf83b12a29903509adf16ccb3b 36 | _clockRate = 16000; 37 | _soundClockRate = 0; 38 | 39 | // default volume scale to 2.0 so 1.0 is twice as loud as PJSIP would normally emit. 40 | _volumeScale = 2.0; 41 | 42 | _account = [GSAccountConfiguration defaultConfiguration]; 43 | return self; 44 | } 45 | 46 | - (void)dealloc { 47 | _account = nil; 48 | } 49 | 50 | 51 | - (id)copyWithZone:(NSZone *)zone { 52 | GSConfiguration *replica = [[[self class] allocWithZone:zone] init]; 53 | 54 | // TODO: Probably better to do via class_copyPropertyList. 55 | replica.logLevel = self.logLevel; 56 | replica.consoleLogLevel = self.consoleLogLevel; 57 | replica.transportType = self.transportType; 58 | 59 | replica.clockRate = self.clockRate; 60 | replica.soundClockRate = self.soundClockRate; 61 | replica.volumeScale = self.volumeScale; 62 | 63 | replica.account = [self.account copy]; 64 | return replica; 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Gossip/GSDispatch.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSDispatch.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import 9 | #import "PJSIP.h" 10 | #import "GSNotifications.h" // almost always needed by importers 11 | 12 | 13 | @interface GSDispatch : NSObject 14 | 15 | + (void)configureCallbacksForAgent:(pjsua_config *)uaConfig; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Gossip/GSDispatch.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSDispatch.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import "GSDispatch.h" 9 | 10 | 11 | void onRegistrationStarted(pjsua_acc_id accountId, pj_bool_t renew); 12 | void onRegistrationState(pjsua_acc_id accountId); 13 | void onIncomingCall(pjsua_acc_id accountId, pjsua_call_id callId, pjsip_rx_data *rdata); 14 | void onCallMediaState(pjsua_call_id callId); 15 | void onCallState(pjsua_call_id callId, pjsip_event *e); 16 | 17 | 18 | static dispatch_queue_t _queue = NULL; 19 | 20 | 21 | @implementation GSDispatch 22 | 23 | + (void)initialize { 24 | _queue = dispatch_queue_create("GSDispatch", DISPATCH_QUEUE_SERIAL); 25 | } 26 | 27 | + (void)configureCallbacksForAgent:(pjsua_config *)uaConfig { 28 | uaConfig->cb.on_reg_started = &onRegistrationStarted; 29 | uaConfig->cb.on_reg_state = &onRegistrationState; 30 | uaConfig->cb.on_incoming_call = &onIncomingCall; 31 | uaConfig->cb.on_call_media_state = &onCallMediaState; 32 | uaConfig->cb.on_call_state = &onCallState; 33 | } 34 | 35 | 36 | #pragma mark - Dispatch sink 37 | 38 | // TODO: May need to implement some form of subscriber filtering 39 | // orthogonaly/globally if we're to scale. But right now a few 40 | // dictionary lookups on the receiver side probably wouldn't hurt much. 41 | 42 | + (void)dispatchRegistrationStarted:(pjsua_acc_id)accountId renew:(pj_bool_t)renew { 43 | NSLog(@"Gossip: dispatchRegistrationStarted(%d, %d)", accountId, renew); 44 | 45 | NSDictionary *info = nil; 46 | info = [NSDictionary dictionaryWithObjectsAndKeys: 47 | [NSNumber numberWithInt:accountId], GSSIPAccountIdKey, 48 | [NSNumber numberWithBool:renew], GSSIPRenewKey, nil]; 49 | 50 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 51 | [center postNotificationName:GSSIPRegistrationDidStartNotification 52 | object:self 53 | userInfo:info]; 54 | } 55 | 56 | + (void)dispatchRegistrationState:(pjsua_acc_id)accountId { 57 | NSLog(@"Gossip: dispatchRegistrationState(%d)", accountId); 58 | 59 | NSDictionary *info = nil; 60 | info = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:accountId] 61 | forKey:GSSIPAccountIdKey]; 62 | 63 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 64 | [center postNotificationName:GSSIPRegistrationStateDidChangeNotification 65 | object:self 66 | userInfo:info]; 67 | } 68 | 69 | + (void)dispatchIncomingCall:(pjsua_acc_id)accountId 70 | callId:(pjsua_call_id)callId 71 | data:(pjsip_rx_data *)data { 72 | NSLog(@"Gossip: dispatchIncomingCall(%d, %d)", accountId, callId); 73 | 74 | NSDictionary *info = nil; 75 | info = [NSDictionary dictionaryWithObjectsAndKeys: 76 | [NSNumber numberWithInt:accountId], GSSIPAccountIdKey, 77 | [NSNumber numberWithInt:callId], GSSIPCallIdKey, 78 | [NSValue valueWithPointer:data], GSSIPDataKey, nil]; 79 | 80 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 81 | [center postNotificationName:GSSIPIncomingCallNotification 82 | object:self 83 | userInfo:info]; 84 | } 85 | 86 | + (void)dispatchCallMediaState:(pjsua_call_id)callId { 87 | NSLog(@"Gossip: dispatchCallMediaState(%d)", callId); 88 | 89 | NSDictionary *info = nil; 90 | info = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:callId] 91 | forKey:GSSIPCallIdKey]; 92 | 93 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 94 | [center postNotificationName:GSSIPCallMediaStateDidChangeNotification 95 | object:self 96 | userInfo:info]; 97 | } 98 | 99 | + (void)dispatchCallState:(pjsua_call_id)callId event:(pjsip_event *)e { 100 | NSLog(@"Gossip: dispatchCallState(%d)", callId); 101 | 102 | NSDictionary *info = nil; 103 | info = [NSDictionary dictionaryWithObjectsAndKeys: 104 | [NSNumber numberWithInt:callId], GSSIPCallIdKey, 105 | [NSValue valueWithPointer:e], GSSIPDataKey, nil]; 106 | 107 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 108 | [center postNotificationName:GSSIPCallStateDidChangeNotification 109 | object:self 110 | userInfo:info]; 111 | } 112 | 113 | @end 114 | 115 | 116 | #pragma mark - C event bridge 117 | 118 | // Bridge C-land callbacks to ObjC-land. 119 | 120 | static inline void dispatch(dispatch_block_t block) { 121 | // autorelease here since events wouldn't be triggered that often. 122 | // + GCD autorelease pool do not have drainage time guarantee (== possible mem headaches). 123 | // See the "Implementing tasks using blocks" section for more info 124 | // REF: http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html 125 | @autoreleasepool { 126 | 127 | // NOTE: Needs to use dispatch_sync() instead of dispatch_async() because we do not know 128 | // the lifetime of the stuff being given to us by PJSIP (e.g. pjsip_rx_data*) so we 129 | // must process it completely before the method ends. 130 | dispatch_sync(_queue, block); 131 | } 132 | } 133 | 134 | 135 | void onRegistrationStarted(pjsua_acc_id accountId, pj_bool_t renew) { 136 | dispatch(^{ [GSDispatch dispatchRegistrationStarted:accountId renew:renew]; }); 137 | } 138 | 139 | void onRegistrationState(pjsua_acc_id accountId) { 140 | dispatch(^{ [GSDispatch dispatchRegistrationState:accountId]; }); 141 | } 142 | 143 | void onIncomingCall(pjsua_acc_id accountId, pjsua_call_id callId, pjsip_rx_data *rdata) { 144 | dispatch(^{ [GSDispatch dispatchIncomingCall:accountId callId:callId data:rdata]; }); 145 | } 146 | 147 | void onCallMediaState(pjsua_call_id callId) { 148 | dispatch(^{ [GSDispatch dispatchCallMediaState:callId]; }); 149 | } 150 | 151 | void onCallState(pjsua_call_id callId, pjsip_event *e) { 152 | dispatch(^{ [GSDispatch dispatchCallState:callId event:e]; }); 153 | } 154 | -------------------------------------------------------------------------------- /Gossip/GSIncomingCall.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSIncomingCall.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/12/12. 6 | // 7 | 8 | #import "GSCall.h" 9 | 10 | 11 | @interface GSIncomingCall : GSCall 12 | 13 | - (id)initWithCallId:(int)callId toAccount:(GSAccount *)account; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Gossip/GSIncomingCall.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSIncomingCall.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/12/12. 6 | // 7 | 8 | #import "GSIncomingCall.h" 9 | #import "GSCall+Private.h" 10 | #import "PJSIP.h" 11 | #import "Util.h" 12 | 13 | 14 | @implementation GSIncomingCall 15 | 16 | - (id)initWithCallId:(int)callId toAccount:(GSAccount *)account { 17 | if (self = [super initWithAccount:account]) { 18 | [self setCallId:callId]; 19 | } 20 | return self; 21 | } 22 | 23 | 24 | - (BOOL)begin { 25 | NSAssert(self.callId != PJSUA_INVALID_ID, @"Call has already ended."); 26 | 27 | GSReturnNoIfFails(pjsua_call_answer(self.callId, 200, NULL, NULL)); 28 | return YES; 29 | } 30 | 31 | - (BOOL)end { 32 | NSAssert(self.callId != PJSUA_INVALID_ID, @"Call has already ended."); 33 | 34 | GSReturnNoIfFails(pjsua_call_hangup(self.callId, 0, NULL, NULL)); 35 | 36 | [self setStatus:GSCallStatusDisconnected]; 37 | [self setCallId:PJSUA_INVALID_ID]; 38 | return YES; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Gossip/GSNotifications.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSNotifications.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/9/12. 6 | // 7 | 8 | #import 9 | 10 | /// Defines notification names 11 | #define GSConstDefine(name_) extern NSString *const name_; 12 | 13 | GSConstDefine(GSSIPRegistrationStateDidChangeNotification); 14 | GSConstDefine(GSSIPRegistrationDidStartNotification); 15 | GSConstDefine(GSSIPCallStateDidChangeNotification); 16 | GSConstDefine(GSSIPIncomingCallNotification); 17 | GSConstDefine(GSSIPCallMediaStateDidChangeNotification); 18 | GSConstDefine(GSSIPVolumeDidChangeNotification); 19 | 20 | GSConstDefine(GSVolumeDidChangeNotification); 21 | 22 | GSConstDefine(GSSIPAccountIdKey); 23 | GSConstDefine(GSSIPRenewKey); 24 | GSConstDefine(GSSIPCallIdKey); 25 | GSConstDefine(GSSIPDataKey); 26 | 27 | GSConstDefine(GSVolumeKey); 28 | GSConstDefine(GSMicVolumeKey); 29 | 30 | 31 | // helper macros 32 | #define GSNotifGetInt(notif_, key_) ([[[notif_ userInfo] objectForKey:key_] intValue]) 33 | #define GSNotifGetBool(notif_, key_) ([[[notif_ userInfo] objectForKey:key_] boolValue]) 34 | #define GSNotifGetString(info_, key_) ((NSString *)[[notif_ userInfo] objectForKey:key_]) 35 | 36 | -------------------------------------------------------------------------------- /Gossip/GSNotifications.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSNotifications.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/9/12. 6 | // 7 | 8 | #import "GSNotifications.h" 9 | 10 | #define GSConstSynthesize(name_) NSString *const name_ = @#name_; 11 | 12 | GSConstSynthesize(GSSIPRegistrationStateDidChangeNotification); 13 | GSConstSynthesize(GSSIPRegistrationDidStartNotification); 14 | GSConstSynthesize(GSSIPCallStateDidChangeNotification); 15 | GSConstSynthesize(GSSIPIncomingCallNotification); 16 | GSConstSynthesize(GSSIPCallMediaStateDidChangeNotification); 17 | 18 | GSConstSynthesize(GSVolumeDidChangeNotification); 19 | 20 | GSConstSynthesize(GSSIPAccountIdKey); 21 | GSConstSynthesize(GSSIPRenewKey); 22 | GSConstSynthesize(GSSIPCallIdKey); 23 | GSConstSynthesize(GSSIPDataKey); 24 | 25 | GSConstSynthesize(GSVolumeKey); 26 | GSConstSynthesize(GSMicVolumeKey); 27 | -------------------------------------------------------------------------------- /Gossip/GSOutgoingCall.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSOutgoingCall.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/12/12. 6 | // 7 | 8 | #import "GSCall.h" 9 | 10 | 11 | @interface GSOutgoingCall : GSCall 12 | 13 | @property (nonatomic, copy, readonly) NSString *remoteUri; 14 | 15 | - (id)initWithRemoteUri:(NSString *)remoteUri 16 | fromAccount:(GSAccount *)account; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Gossip/GSOutgoingCall.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSOutgoingCall.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/12/12. 6 | // 7 | 8 | #import "GSOutgoingCall.h" 9 | #import "GSCall+Private.h" 10 | #import "PJSIP.h" 11 | #import "Util.h" 12 | 13 | 14 | @implementation GSOutgoingCall 15 | 16 | @synthesize remoteUri = _remoteUri; 17 | 18 | - (id)initWithRemoteUri:(NSString *)remoteUri fromAccount:(GSAccount *)account { 19 | if (self = [super initWithAccount:account]) { 20 | _remoteUri = [remoteUri copy]; 21 | } 22 | return self; 23 | } 24 | 25 | - (void)dealloc { 26 | _remoteUri = nil; 27 | } 28 | 29 | 30 | - (BOOL)begin { 31 | if (![_remoteUri hasPrefix:@"sip:"]) 32 | _remoteUri = [@"sip:" stringByAppendingString:_remoteUri]; 33 | 34 | pj_str_t remoteUri = [GSPJUtil PJStringWithString:_remoteUri]; 35 | 36 | pjsua_call_setting callSetting; 37 | pjsua_call_setting_default(&callSetting); 38 | callSetting.aud_cnt = 1; 39 | callSetting.vid_cnt = 0; // TODO: Video calling support? 40 | 41 | pjsua_call_id callId; 42 | GSReturnNoIfFails(pjsua_call_make_call(self.account.accountId, &remoteUri, &callSetting, NULL, NULL, &callId)); 43 | 44 | [self setCallId:callId]; 45 | return YES; 46 | } 47 | 48 | - (BOOL)end { 49 | NSAssert(self.callId != PJSUA_INVALID_ID, @"Call has not begun yet."); 50 | GSReturnNoIfFails(pjsua_call_hangup(self.callId, 0, NULL, NULL)); 51 | 52 | [self setStatus:GSCallStatusDisconnected]; 53 | [self setCallId:PJSUA_INVALID_ID]; 54 | return YES; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /Gossip/GSPJUtil.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSPJUtil.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import 9 | #import "PJSIP.h" 10 | 11 | 12 | /// General utilities for working with PJSIP in ObjC land. 13 | /** Had to use a static class instead since categories cause compilation problems 14 | * when linked to an application. */ 15 | @interface GSPJUtil : NSObject 16 | 17 | /// Creates an NSError from the given PJSIP status using PJSIP macros and functions. 18 | + (NSError *)errorWithSIPStatus:(pj_status_t)status; 19 | 20 | /// Creates NSString from pj_str_t. Instance usable as long as pj_str_t lives. 21 | + (NSString *)stringWithPJString:(const pj_str_t *)pjString; 22 | 23 | /// Creates pj_str_t from NSString. Instance lifetime depends on the NSString instance. 24 | + (pj_str_t)PJStringWithString:(NSString *)string; 25 | 26 | /// Creates pj_str_t from NSString prefixed with "sip:". Instance lifetime depends on the NSString instance. 27 | + (pj_str_t)PJAddressWithString:(NSString *)string; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Gossip/GSPJUtil.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSPJUtil.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import "GSPJUtil.h" 9 | 10 | 11 | @implementation GSPJUtil 12 | 13 | + (NSError *)errorWithSIPStatus:(pj_status_t)status { 14 | int errNumber = PJSIP_ERRNO_FROM_SIP_STATUS(status); 15 | 16 | pj_size_t bufferSize = sizeof(char) * 255; 17 | NSMutableData *data = [NSMutableData dataWithLength:bufferSize]; 18 | char *buffer = [data mutableBytes]; 19 | pj_strerror(status, buffer, bufferSize); 20 | 21 | NSString *errorStr = [NSString stringWithCString:buffer encoding:NSASCIIStringEncoding]; 22 | NSDictionary *info = nil; 23 | info = [NSDictionary dictionaryWithObjectsAndKeys: 24 | errorStr, NSLocalizedDescriptionKey, 25 | [NSNumber numberWithInt:status], @"pj_status_t", 26 | [NSNumber numberWithInt:errNumber], @"PJSIP_ERRNO_FORM_SIP_STATUS", nil]; 27 | 28 | NSError *err = nil; 29 | err = [NSError errorWithDomain:@"pjsip.org" 30 | code:PJSIP_ERRNO_FROM_SIP_STATUS(status) 31 | userInfo:info]; 32 | 33 | return err; 34 | } 35 | 36 | 37 | + (NSString *)stringWithPJString:(const pj_str_t *)pjString { 38 | NSString *result = [NSString alloc]; 39 | result = [result initWithBytesNoCopy:pjString->ptr 40 | length:pjString->slen 41 | encoding:NSASCIIStringEncoding 42 | freeWhenDone:NO]; 43 | 44 | return result; 45 | } 46 | 47 | + (pj_str_t)PJStringWithString:(NSString *)string { 48 | const char *cStr = [string cStringUsingEncoding:NSASCIIStringEncoding]; // TODO: UTF8? 49 | 50 | pj_str_t result; 51 | pj_cstr(&result, cStr); 52 | return result; 53 | } 54 | 55 | + (pj_str_t)PJAddressWithString:(NSString *)string { 56 | return [self PJStringWithString:[@"sip:" stringByAppendingString:string]]; 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /Gossip/GSRingback.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSRingback.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 8/15/12. 6 | // 7 | // 8 | 9 | #import 10 | 11 | 12 | /// Ringback sound player. 13 | @interface GSRingback : NSObject 14 | 15 | @property (nonatomic, readonly) BOOL isPlaying; ///< Returns wether ringback is already playing or not. 16 | @property (nonatomic, readonly) float volume; ///< Returns current ringback volume. 17 | 18 | /// Creates GSRingback instance with ringback tone from the specified filename. 19 | + (id)ringbackWithSoundNamed:(NSString *)filename; 20 | 21 | - (BOOL)setVolume:(float)volume; ///< Sets ringback volume. This value is subject to GSConfiguration.volumeScale. 22 | 23 | - (BOOL)play; ///< Plays the ringback sound on the default sound device. 24 | - (BOOL)stop; ///< Stops the playback. 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Gossip/GSRingback.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSRingback.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 8/15/12. 6 | // 7 | // 8 | 9 | #import "GSRingback.h" 10 | #import "GSUserAgent.h" 11 | #import "GSUserAgent+Private.h" 12 | #import "PJSIP.h" 13 | #import "Util.h" 14 | 15 | 16 | @implementation GSRingback { 17 | float _volume; 18 | float _volumeScale; 19 | 20 | pjsua_conf_port_id _confPort; 21 | pjsua_player_id _playerId; 22 | } 23 | 24 | + (id)ringbackWithSoundNamed:(NSString *)filename { 25 | return [[self alloc] initWithSoundNamed:filename]; 26 | } 27 | 28 | 29 | - (id)initWithSoundNamed:(NSString *)filename { 30 | if (self = [super init]) { 31 | NSBundle *bundle = [NSBundle mainBundle]; 32 | 33 | _isPlaying = NO; 34 | _confPort = PJSUA_INVALID_ID; 35 | _playerId = PJSUA_INVALID_ID; 36 | 37 | _volumeScale = [GSUserAgent sharedAgent].configuration.volumeScale; 38 | _volume = 0.5 / _volumeScale; // half volume by default 39 | 40 | // resolve bundle filename 41 | filename = [filename lastPathComponent]; 42 | filename = [bundle pathForResource:[filename stringByDeletingPathExtension] 43 | ofType:[filename pathExtension]]; 44 | NSLog(@"Gossip: ringbackWithSoundNamed: %@", filename); 45 | 46 | // create pjsua media playlist 47 | const pj_str_t filenames[] = { [GSPJUtil PJStringWithString:filename] }; 48 | GSReturnNilIfFails(pjsua_playlist_create(filenames, 1, NULL, 0, &_playerId)); 49 | 50 | _confPort = pjsua_player_get_conf_port(_playerId); 51 | } 52 | return self; 53 | } 54 | 55 | - (void)dealloc { 56 | if (_playerId != PJSUA_INVALID_ID) { 57 | GSLogIfFails(pjsua_player_destroy(_playerId)); 58 | _playerId = PJSUA_INVALID_ID; 59 | } 60 | } 61 | 62 | 63 | - (BOOL)setVolume:(float)volume { 64 | GSAssert(0.0 <= volume && volume <= 1.0, @"Volume value must be between 0.0 and 1.0"); 65 | 66 | _volume = volume; 67 | volume *= _volumeScale; 68 | GSReturnNoIfFails(pjsua_conf_adjust_rx_level(_confPort, volume)); 69 | GSReturnNoIfFails(pjsua_conf_adjust_tx_level(_confPort, volume)); 70 | 71 | return YES; 72 | } 73 | 74 | 75 | - (BOOL)play { 76 | GSAssert(!_isPlaying, @"Already connected to a call."); 77 | 78 | GSReturnNoIfFails(pjsua_conf_connect(_confPort, 0)); 79 | _isPlaying = YES; 80 | return YES; 81 | } 82 | 83 | - (BOOL)stop { 84 | GSAssert(_isPlaying, @"Not connected to a call."); 85 | 86 | GSReturnNoIfFails(pjsua_conf_disconnect(_confPort, 0)); 87 | _isPlaying = NO; 88 | return YES; 89 | } 90 | 91 | 92 | @end 93 | -------------------------------------------------------------------------------- /Gossip/GSUserAgent+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSUserAgent+Private.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/18/12. 6 | // 7 | 8 | #import "GSUserAgent.h" 9 | #import "GSConfiguration.h" 10 | 11 | 12 | @interface GSUserAgent (Private) 13 | 14 | @property (nonatomic, readonly) GSConfiguration *configuration; 15 | @property (nonatomic, readwrite) GSUserAgentState status; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Gossip/GSUserAgent.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSUserAgent.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/5/12. 6 | // 7 | 8 | #import 9 | #import "GSAccount.h" 10 | #import "GSConfiguration.h" 11 | 12 | 13 | typedef enum { 14 | GSUserAgentStateUninitialized = 0, 15 | GSUserAgentStateCreated = 1, 16 | GSUserAgentStateConfigured = 2, 17 | GSUserAgentStateStarted = 3, 18 | GSUserAgentStateDestroyed = -1, // TODO: Remove? Since it's equivalent to uninitialized. 19 | } GSUserAgentState; 20 | 21 | 22 | /// Mains SIP user agent interface. Applications should configure the shared instance on startup. 23 | /** Only a single GSUserAgent may be created for each application since PJSIP only supports a single user agent at a time. 24 | * Applications should follow the following steps to initialize the agent: 25 | * 26 | * 1. Obtain an instance of this class using sharedAgent() 27 | * 2. Creates and configure an instance of GSConfiguration. 28 | * 3. Calls configure:() to configure the agent. 29 | * 4. (Optional) GSAccount::connect to the SIP server 30 | */ 31 | @interface GSUserAgent : NSObject 32 | 33 | @property (nonatomic, strong, readonly) GSAccount *account; ///< Default GSAccount instance with the configured SIP account registration. 34 | @property (nonatomic, readonly) GSUserAgentState status; ///< User agent configuration state. Supports KVO notification. 35 | 36 | /// Obtains the shared user agent instance. 37 | + (GSUserAgent *)sharedAgent; 38 | 39 | /// Configure the agent for use. 40 | /** This method must be called on application startup and before using any SIP functionality. 41 | * Check http://www.pjsip.org/pjsip/docs/html/structpjsua__acc__config.htm for additional reference. */ 42 | - (BOOL)configure:(GSConfiguration *)config; 43 | 44 | /// Starts the user agent. 45 | /** This method effectively cause PJSIP to begin connecting to the configured SIP server 46 | * using the credentials specified when configure:() was called. A GSAccount instance 47 | * will be created and used for registration automatically. 48 | * 49 | * After a successful start, application should call GSAccount::connect() to connect 50 | * to the SIP server to listen for incoming calls (or making outgoing calls.) 51 | */ 52 | - (BOOL)start; 53 | 54 | /// Resets the user agent to an unconfigured state. 55 | /** You will need to call GSUserAgent::configure() and GSUserAgent::start() again. 56 | * You may use this method to resets and reconnect user agent to a different account. 57 | */ 58 | - (BOOL)reset; 59 | 60 | /// Gets an array of GSCodecInfo for codecs loaded by PJSIP. 61 | - (NSArray *)arrayOfAvailableCodecs; 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /Gossip/GSUserAgent.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSUserAgent.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/5/12. 6 | // 7 | 8 | #import "GSUserAgent.h" 9 | #import "GSUserAgent+Private.h" 10 | #import "GSCodecInfo.h" 11 | #import "GSCodecInfo+Private.h" 12 | #import "GSDispatch.h" 13 | #import "PJSIP.h" 14 | #import "Util.h" 15 | 16 | 17 | @implementation GSUserAgent { 18 | GSConfiguration *_config; 19 | pjsua_transport_id _transportId; 20 | } 21 | 22 | @synthesize account = _account; 23 | @synthesize status = _status; 24 | 25 | + (GSUserAgent *)sharedAgent { 26 | static dispatch_once_t onceToken; 27 | static GSUserAgent *agent = nil; 28 | dispatch_once(&onceToken, ^{ agent = [[GSUserAgent alloc] init]; }); 29 | 30 | return agent; 31 | } 32 | 33 | 34 | - (id)init { 35 | if (self = [super init]) { 36 | _account = nil; 37 | _config = nil; 38 | 39 | _transportId = PJSUA_INVALID_ID; 40 | _status = GSUserAgentStateUninitialized; 41 | } 42 | return self; 43 | } 44 | 45 | - (void)dealloc { 46 | if (_transportId != PJSUA_INVALID_ID) { 47 | pjsua_transport_close(_transportId, PJ_TRUE); 48 | _transportId = PJSUA_INVALID_ID; 49 | } 50 | 51 | if (_status >= GSUserAgentStateConfigured) { 52 | pjsua_destroy(); 53 | } 54 | 55 | _account = nil; 56 | _config = nil; 57 | _status = GSUserAgentStateDestroyed; 58 | } 59 | 60 | 61 | - (GSConfiguration *)configuration { 62 | return _config; 63 | } 64 | 65 | - (GSUserAgentState)status { 66 | return _status; 67 | } 68 | 69 | - (void)setStatus:(GSUserAgentState)status { 70 | [self willChangeValueForKey:@"status"]; 71 | _status = status; 72 | [self didChangeValueForKey:@"status"]; 73 | } 74 | 75 | 76 | - (BOOL)configure:(GSConfiguration *)config { 77 | GSAssert(!_config, @"Gossip: User agent is already configured."); 78 | _config = [config copy]; 79 | 80 | // create agent 81 | GSReturnNoIfFails(pjsua_create()); 82 | [self setStatus:GSUserAgentStateCreated]; 83 | 84 | // configure agent 85 | pjsua_config uaConfig; 86 | pjsua_logging_config logConfig; 87 | pjsua_media_config mediaConfig; 88 | 89 | pjsua_config_default(&uaConfig); 90 | [GSDispatch configureCallbacksForAgent:&uaConfig]; 91 | 92 | pjsua_logging_config_default(&logConfig); 93 | logConfig.level = _config.logLevel; 94 | logConfig.console_level = _config.consoleLogLevel; 95 | 96 | pjsua_media_config_default(&mediaConfig); 97 | mediaConfig.clock_rate = _config.clockRate; 98 | mediaConfig.snd_clock_rate = _config.soundClockRate; 99 | mediaConfig.ec_tail_len = 0; // not sure what this does (Siphon use this.) 100 | 101 | GSReturnNoIfFails(pjsua_init(&uaConfig, &logConfig, &mediaConfig)); 102 | 103 | // Configure the DNS resolvers to also handle SRV records 104 | pjsip_endpoint* endpoint = pjsua_get_pjsip_endpt(); 105 | pj_dns_resolver* resolver; 106 | pj_str_t google_dns = [GSPJUtil PJStringWithString:@"8.8.8.8"]; 107 | struct pj_str_t servers[] = { google_dns }; 108 | GSReturnNoIfFails(pjsip_endpt_create_resolver(endpoint, &resolver)); 109 | GSReturnNoIfFails(pj_dns_resolver_set_ns(resolver, 1, servers, nil)); 110 | GSReturnNoIfFails(pjsip_endpt_set_resolver(endpoint, resolver)); 111 | 112 | // create UDP transport 113 | // TODO: Make configurable? (which transport type to use/other transport opts) 114 | // TODO: Make separate class? since things like public_addr might be useful to some. 115 | pjsua_transport_config transportConfig; 116 | pjsua_transport_config_default(&transportConfig); 117 | 118 | pjsip_transport_type_e transportType = 0; 119 | switch (_config.transportType) { 120 | case GSUDPTransportType: transportType = PJSIP_TRANSPORT_UDP; break; 121 | case GSUDP6TransportType: transportType = PJSIP_TRANSPORT_UDP6; break; 122 | case GSTCPTransportType: transportType = PJSIP_TRANSPORT_TCP; break; 123 | case GSTCP6TransportType: transportType = PJSIP_TRANSPORT_TCP6; break; 124 | } 125 | 126 | GSReturnNoIfFails(pjsua_transport_create(transportType, &transportConfig, &_transportId)); 127 | [self setStatus:GSUserAgentStateConfigured]; 128 | 129 | // configure account 130 | _account = [[GSAccount alloc] init]; 131 | return [_account configure:_config.account]; 132 | } 133 | 134 | 135 | - (BOOL)start { 136 | GSReturnNoIfFails(pjsua_start()); 137 | [self setStatus:GSUserAgentStateStarted]; 138 | return YES; 139 | } 140 | 141 | - (BOOL)reset { 142 | [_account disconnect]; 143 | 144 | // needs to nil account before pjsua_destroy so pjsua_acc_del succeeds. 145 | _transportId = PJSUA_INVALID_ID; 146 | _account = nil; 147 | _config = nil; 148 | NSLog(@"Destroying..."); 149 | GSReturnNoIfFails(pjsua_destroy()); 150 | [self setStatus:GSUserAgentStateDestroyed]; 151 | return YES; 152 | } 153 | 154 | 155 | - (NSArray *)arrayOfAvailableCodecs { 156 | GSAssert(!!_config, @"Gossip: User agent not configured."); 157 | 158 | NSMutableArray *arr = [[NSMutableArray alloc] init]; 159 | 160 | unsigned int count = 255; 161 | pjsua_codec_info codecs[count]; 162 | GSReturnNilIfFails(pjsua_enum_codecs(codecs, &count)); 163 | 164 | for (int i = 0; i < count; i++) { 165 | pjsua_codec_info pjCodec = codecs[i]; 166 | 167 | GSCodecInfo *codec = [GSCodecInfo alloc]; 168 | codec = [codec initWithCodecInfo:&pjCodec]; 169 | [arr addObject:codec]; 170 | } 171 | 172 | return [NSArray arrayWithArray:arr]; 173 | } 174 | 175 | @end 176 | -------------------------------------------------------------------------------- /Gossip/Gossip.h: -------------------------------------------------------------------------------- 1 | // 2 | // Gossip.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | /** /file 9 | * /brief Convenience import for application developer. 10 | */ 11 | 12 | 13 | #import "GSConfiguration.h" 14 | #import "GSAccountConfiguration.h" 15 | #import "GSUserAgent.h" 16 | #import "GSAccount.h" 17 | #import "GSCall.h" 18 | #import "GSCodecInfo.h" 19 | -------------------------------------------------------------------------------- /Gossip/PJSIP.h: -------------------------------------------------------------------------------- 1 | // 2 | // PJSIP.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/5/12. 6 | // 7 | 8 | /// Shim for loading PJSIP stuff with all the required #defines 9 | #import "TargetConditionals.h" 10 | 11 | // NOTE: Must be placed *before* any pjsip stuff. 12 | #ifndef PJ_IS_LITTLE_ENDIAN 13 | #define PJ_IS_LITTLE_ENDIAN 1 14 | #endif 15 | 16 | #ifndef PJ_IS_BIG_ENDIAN 17 | #define PJ_IS_BIG_ENDIAN 0 18 | #endif 19 | 20 | #ifndef PJMEDIA_HAS_VIDEO 21 | #define PJMEDIA_HAS_VIDEO 0 22 | #endif 23 | 24 | // Workaround buggy PJSIP arch detection logic when building for the phone. Simulator builds seems 25 | // to be okay. 26 | #ifndef PJ_HAS_PENTIUM 27 | # ifdef TARGET_IPHONE_SIMULATOR 28 | # define PJ_M_X86_64 29 | # else 30 | # define PJ_M_ARMV4 1 31 | # endif 32 | #endif 33 | 34 | // COMPAT: Uncomment to fix darwin typedef conflict w/ PJSIP socklen_t when linking against ios5.1 35 | //#ifndef _SOCKLEN_T 36 | //#define _SOCKLEN_T 1 37 | //#endif 38 | #import 39 | 40 | // Place any required PJSIP includes/imports *below* this line 41 | #import 42 | #import 43 | #import 44 | #import 45 | #import 46 | #import 47 | #import 48 | #import 49 | -------------------------------------------------------------------------------- /Gossip/Util.h: -------------------------------------------------------------------------------- 1 | // 2 | // Util.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | 9 | // additional util imports 10 | #import "GSPJUtil.h" 11 | 12 | 13 | // just in case we need to compile w/o assertions 14 | #define GSAssert NSAssert 15 | 16 | 17 | // PJSIP status check macros 18 | #define GSLogSipError(status_) \ 19 | NSLog(@"Gossip: %@", [GSPJUtil errorWithSIPStatus:status_]); 20 | 21 | #define GSLogIfFails(aStatement_) do { \ 22 | pj_status_t status = (aStatement_); \ 23 | if (status != PJ_SUCCESS) \ 24 | GSLogSipError(status); \ 25 | } while (0) 26 | 27 | #define GSReturnValueIfFails(aStatement_, returnValue_) do { \ 28 | pj_status_t status = (aStatement_); \ 29 | if (status != PJ_SUCCESS) { \ 30 | GSLogSipError(status); \ 31 | return returnValue_; \ 32 | } \ 33 | } while(0) 34 | 35 | #define GSReturnIfFails(aStatement_) GSReturnValueIfFails(aStatement_, ) 36 | #define GSReturnNoIfFails(aStatement_) GSReturnValueIfFails(aStatement_, NO) 37 | #define GSReturnNilIfFails(aStatement_) GSReturnValueIfFails(aStatement_, nil) 38 | -------------------------------------------------------------------------------- /GossipExample/GSEAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSEAppDelegate.h 3 | // GSGossipExample 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | 9 | @interface GSEAppDelegate : UIResponder 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /GossipExample/GSEAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSEAppDelegate.m 3 | // GSGossipExample 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import "GSEAppDelegate.h" 9 | #import "GSERootViewController.h" 10 | 11 | #import "GSConfiguration.h" 12 | #import "GSUserAgent.h" 13 | 14 | 15 | @implementation GSEAppDelegate { 16 | UIWindow *_window; 17 | } 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | 21 | // initialize view 22 | GSERootViewController *root = [[GSERootViewController alloc] init]; 23 | 24 | _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 25 | [_window setRootViewController:root]; 26 | [_window makeKeyAndVisible]; 27 | 28 | return YES; 29 | } 30 | 31 | - (void)applicationWillResignActive:(UIApplication *)application { } 32 | - (void)applicationDidEnterBackground:(UIApplication *)application { } 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { } 34 | - (void)applicationDidBecomeActive:(UIApplication *)application { } 35 | - (void)applicationWillTerminate:(UIApplication *)application { } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /GossipExample/GSECallInitController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSECallInitController.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/9/12. 6 | // 7 | 8 | 9 | @interface GSECallInitController : NSObject 10 | 11 | @property (nonatomic, unsafe_unretained) UINavigationController *navigationController; 12 | 13 | - (void)makeNewCall; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /GossipExample/GSECallInitController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSECallInitController.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/9/12. 6 | // 7 | 8 | #import "GSECallInitController.h" 9 | #import "GSECallViewController.h" 10 | 11 | 12 | @interface GSECallInitController () @end 13 | 14 | 15 | @implementation GSECallInitController { 16 | NSString *_address; 17 | BOOL _addressIsLandline; 18 | } 19 | 20 | @synthesize navigationController = _navigationController; 21 | 22 | - (id)init { 23 | if (self = [super init]) { 24 | _address = nil; 25 | _addressIsLandline = NO; 26 | } 27 | return self; 28 | } 29 | 30 | - (void)dealloc { 31 | _address = nil; 32 | } 33 | 34 | 35 | - (void)makeNewCall { 36 | [self showLandlineChoices]; 37 | } 38 | 39 | 40 | - (void)showLandlineChoices { 41 | UIActionSheet *sheet = [[UIActionSheet alloc] init]; 42 | [sheet setTitle:@"Select Address Type"]; 43 | [sheet setDelegate:self]; 44 | [sheet addButtonWithTitle:@"Landline Number"]; 45 | [sheet addButtonWithTitle:@"SIP Address"]; 46 | [sheet addButtonWithTitle:@"Cancel"]; 47 | [sheet setCancelButtonIndex:2]; 48 | [sheet showInView:[_navigationController view]]; 49 | } 50 | 51 | - (void)showNumberPrompt { 52 | UIAlertView *alertView = [[UIAlertView alloc] init]; 53 | [alertView setAlertViewStyle:UIAlertViewStylePlainTextInput]; 54 | [alertView setTitle:@"Enter Address (or Number)"]; 55 | [[alertView textFieldAtIndex:0] setText:@"chakrit2@getonsip.com"]; 56 | [alertView setDelegate:self]; 57 | [alertView addButtonWithTitle:@"Cancel"]; 58 | [alertView addButtonWithTitle:@"Call"]; 59 | [alertView setCancelButtonIndex:0]; 60 | [alertView show]; 61 | } 62 | 63 | 64 | - (void)userMadeLandlineChoice:(BOOL)isLandline { 65 | _addressIsLandline = isLandline; 66 | [self showNumberPrompt]; 67 | } 68 | 69 | - (void)userDidEnterAddress:(NSString *)address { 70 | _address = [address copy]; 71 | [self makeTheCall]; 72 | } 73 | 74 | 75 | - (void)makeTheCall { 76 | // TODO: add call view controller 77 | GSAccount *account = [GSUserAgent sharedAgent].account; 78 | GSCall *call = [GSCall outgoingCallToUri:_address fromAccount:account]; 79 | 80 | GSECallViewController *controller = [[GSECallViewController alloc] init]; 81 | controller.call = call; 82 | 83 | [_navigationController pushViewController:controller animated:YES]; 84 | } 85 | 86 | 87 | #pragma mark - UIActionSheetDelegate 88 | 89 | - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex { 90 | if (buttonIndex == [actionSheet cancelButtonIndex]) 91 | return; 92 | 93 | [self userMadeLandlineChoice:(buttonIndex == 0)]; 94 | } 95 | 96 | 97 | #pragma mark - UIAlertViewDelegate 98 | 99 | - (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView { 100 | UITextField *textField = [alertView textFieldAtIndex:0]; 101 | return [[textField text] length] > 0; 102 | } 103 | 104 | - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { 105 | if (buttonIndex == [alertView cancelButtonIndex]) 106 | return; 107 | 108 | [self userDidEnterAddress:[[alertView textFieldAtIndex:0] text]]; 109 | } 110 | 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /GossipExample/GSECallViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSECallViewController.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/9/12. 6 | // 7 | 8 | #import "Gossip.h" 9 | 10 | 11 | @interface GSECallViewController : UIViewController 12 | 13 | @property (nonatomic, strong) GSCall *call; 14 | 15 | @property (nonatomic, strong) IBOutlet UILabel *statusLabel; 16 | @property (nonatomic, strong) IBOutlet UIButton *hangupButton; 17 | 18 | - (IBAction)userDidTapHangUp; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /GossipExample/GSECallViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSECallViewController.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/9/12. 6 | // 7 | 8 | #import "GSECallViewController.h" 9 | 10 | 11 | @implementation GSECallViewController 12 | 13 | @synthesize call = _call; 14 | 15 | @synthesize statusLabel = _statusLabel; 16 | @synthesize hangupButton = _hangupButton; 17 | 18 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 19 | if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 20 | _call = nil; 21 | _statusLabel = nil; 22 | _hangupButton = nil; 23 | } 24 | return self; 25 | } 26 | 27 | - (void)dealloc { 28 | self.call = nil; 29 | 30 | _statusLabel = nil; 31 | _hangupButton = nil; 32 | } 33 | 34 | 35 | - (NSString *)title { 36 | return @"Call"; 37 | } 38 | 39 | - (void)setCall:(GSCall *)call { 40 | [self willChangeValueForKey:@"call"]; 41 | [_call removeObserver:self forKeyPath:@"status"]; 42 | _call = call; 43 | [_call addObserver:self 44 | forKeyPath:@"status" 45 | options:NSKeyValueObservingOptionInitial 46 | context:nil]; 47 | [self didChangeValueForKey:@"call"]; 48 | } 49 | 50 | 51 | - (void)viewDidLoad { 52 | [[self navigationItem] setHidesBackButton:YES]; 53 | [_hangupButton setEnabled:NO]; 54 | 55 | // update calling status 56 | [self callStatusDidChange]; 57 | 58 | // begin calling after 1s 59 | const double delayInSeconds = 1.0; 60 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 61 | 62 | __block GSCall *call_ = _call; 63 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 64 | [call_ begin]; 65 | }); 66 | } 67 | 68 | 69 | - (void)userDidTapHangUp { 70 | [_call end]; 71 | } 72 | 73 | 74 | - (void)callStatusDidChange { 75 | switch (_call.status) { 76 | case GSCallStatusReady: { 77 | [_statusLabel setText:@"Ready."]; 78 | [_hangupButton setEnabled:NO]; 79 | } break; 80 | 81 | case GSCallStatusConnecting: { 82 | [_statusLabel setText:@"Connecting..."]; 83 | [_hangupButton setEnabled:NO]; 84 | } break; 85 | 86 | case GSCallStatusCalling: { 87 | [_statusLabel setText:@"Calling..."]; 88 | [_hangupButton setEnabled:YES]; 89 | } break; 90 | 91 | case GSCallStatusConnected: { 92 | [_statusLabel setText:@"Connected."]; 93 | [_hangupButton setEnabled:YES]; 94 | } break; 95 | 96 | case GSCallStatusDisconnected: { 97 | [_statusLabel setText:@"Disconnected."]; 98 | [_hangupButton setEnabled:YES]; 99 | 100 | // pop view after 2s 101 | const double delayInSeconds = 2.0; 102 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 103 | 104 | __block id self_ = self; 105 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 106 | [[self_ navigationController] popViewControllerAnimated:YES]; 107 | }); 108 | } break; 109 | } 110 | } 111 | 112 | 113 | - (void)observeValueForKeyPath:(NSString *)keyPath 114 | ofObject:(id)object 115 | change:(NSDictionary *)change 116 | context:(void *)context { 117 | if ([keyPath isEqualToString:@"status"]) 118 | [self callStatusDidChange]; 119 | } 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /GossipExample/GSECallViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1296 5 | 11E53 6 | 2182 7 | 1138.47 8 | 569.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 1181 12 | 13 | 14 | IBUIButton 15 | IBUIView 16 | IBUILabel 17 | IBProxyObject 18 | 19 | 20 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 21 | 22 | 23 | PluginDependencyRecalculationVersion 24 | 25 | 26 | 27 | 28 | IBFilesOwner 29 | IBCocoaTouchFramework 30 | 31 | 32 | IBFirstResponder 33 | IBCocoaTouchFramework 34 | 35 | 36 | 37 | 274 38 | 39 | 40 | 41 | 292 42 | {{20, 20}, {280, 21}} 43 | 44 | 45 | 46 | _NS:9 47 | NO 48 | YES 49 | 7 50 | NO 51 | IBCocoaTouchFramework 52 | Label 53 | 54 | 1 55 | MCAwIDAAA 56 | 57 | 58 | 0 59 | 10 60 | 61 | 1 62 | 17 63 | 64 | 65 | Helvetica 66 | 17 67 | 16 68 | 69 | 70 | 71 | 72 | 292 73 | {{20, 359}, {280, 37}} 74 | 75 | 76 | 77 | _NS:9 78 | NO 79 | IBCocoaTouchFramework 80 | 0 81 | 0 82 | 1 83 | Hang Up 84 | 85 | 3 86 | MQA 87 | 88 | 89 | 1 90 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 91 | 92 | 93 | 3 94 | MC41AA 95 | 96 | 97 | 2 98 | 15 99 | 100 | 101 | Helvetica-Bold 102 | 15 103 | 16 104 | 105 | 106 | 107 | {{0, 64}, {320, 416}} 108 | 109 | 110 | 111 | 112 | 3 113 | MQA 114 | 115 | 2 116 | 117 | 118 | 119 | 120 | NO 121 | 122 | IBCocoaTouchFramework 123 | 124 | 125 | 126 | 127 | 128 | 129 | view 130 | 131 | 132 | 133 | 3 134 | 135 | 136 | 137 | statusLabel 138 | 139 | 140 | 141 | 5 142 | 143 | 144 | 145 | hangupButton 146 | 147 | 148 | 149 | 7 150 | 151 | 152 | 153 | userDidTapHangUp 154 | 155 | 156 | 7 157 | 158 | 8 159 | 160 | 161 | 162 | 163 | 164 | 0 165 | 166 | 167 | 168 | 169 | 170 | 1 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | -1 180 | 181 | 182 | File's Owner 183 | 184 | 185 | -2 186 | 187 | 188 | 189 | 190 | 4 191 | 192 | 193 | 194 | 195 | 6 196 | 197 | 198 | 199 | 200 | 201 | 202 | GSECallViewController 203 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 204 | UIResponder 205 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 206 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 207 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 208 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 209 | 210 | 211 | 212 | 213 | 214 | 8 215 | 216 | 217 | 218 | 219 | GSECallViewController 220 | UIViewController 221 | 222 | userDidTapHangUp 223 | id 224 | 225 | 226 | userDidTapHangUp 227 | 228 | userDidTapHangUp 229 | id 230 | 231 | 232 | 233 | UIButton 234 | UILabel 235 | 236 | 237 | 238 | hangupButton 239 | UIButton 240 | 241 | 242 | statusLabel 243 | UILabel 244 | 245 | 246 | 247 | IBProjectSource 248 | ./Classes/GSECallViewController.h 249 | 250 | 251 | 252 | 253 | 0 254 | IBCocoaTouchFramework 255 | 256 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 257 | 258 | 259 | YES 260 | 3 261 | 1181 262 | 263 | 264 | -------------------------------------------------------------------------------- /GossipExample/GSECodecsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSECodecsViewController.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/13/12. 6 | // 7 | 8 | 9 | @interface GSECodecsViewController : UIViewController 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /GossipExample/GSECodecsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSECodecsViewController.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/13/12. 6 | // 7 | 8 | #import "GSECodecsViewController.h" 9 | #import "Gossip.h" 10 | 11 | 12 | @interface GSECodecsViewController () @end 13 | 14 | 15 | @implementation GSECodecsViewController { 16 | NSArray *_codecs; 17 | } 18 | 19 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 20 | if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 21 | _codecs = [[GSUserAgent sharedAgent] arrayOfAvailableCodecs]; 22 | } 23 | return self; 24 | } 25 | 26 | - (void)loadView { 27 | UITableView *tableView = [UITableView alloc]; 28 | tableView = [tableView initWithFrame:CGRectMake(0, 0, 320, 480) 29 | style:UITableViewStyleGrouped]; 30 | [tableView setDataSource:self]; 31 | [tableView setDelegate:self]; 32 | 33 | UIView *view = [[UIView alloc] init]; 34 | [view addSubview:tableView]; 35 | [self setView:view]; 36 | } 37 | 38 | - (void)dealloc { 39 | _codecs = nil; 40 | } 41 | 42 | 43 | - (NSString *)title { 44 | return @"Codecs"; 45 | } 46 | 47 | 48 | #pragma mark - UITableViewDataSource && UITableViewDelegate 49 | 50 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 51 | return 1; 52 | } 53 | 54 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 55 | return [_codecs count]; 56 | } 57 | 58 | - (UITableViewCell *)tableView:(UITableView *)tableView 59 | cellForRowAtIndexPath:(NSIndexPath *)indexPath { 60 | static NSString *const CellId = @"codec"; 61 | 62 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellId]; 63 | if (!cell) { 64 | cell = [UITableViewCell alloc]; 65 | cell = [cell initWithStyle:UITableViewCellStyleValue1 66 | reuseIdentifier:CellId]; 67 | } 68 | 69 | GSCodecInfo *codec = [_codecs objectAtIndex:[indexPath row]]; 70 | [[cell textLabel] setText:codec.codecId]; 71 | 72 | NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; 73 | [formatter setNumberStyle:NSNumberFormatterBehaviorDefault]; 74 | [formatter setLocale:[NSLocale systemLocale]]; 75 | 76 | NSNumber *priorityNum = [NSNumber numberWithUnsignedInteger:codec.priority]; 77 | NSString *priorityStr = [formatter stringFromNumber:priorityNum]; 78 | [[cell detailTextLabel] setText:priorityStr]; 79 | return cell; 80 | } 81 | 82 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 83 | [tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] 84 | animated:YES 85 | scrollPosition:UITableViewScrollPositionNone]; 86 | 87 | GSCodecInfo *codec = [_codecs objectAtIndex:[indexPath row]]; 88 | [codec disable]; 89 | [tableView reloadData]; 90 | } 91 | 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /GossipExample/GSEConfigurationViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSEConfigurationViewController.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | 9 | @interface GSEConfigurationViewController : UIViewController 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /GossipExample/GSEConfigurationViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSEConfigurationViewController.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import "GSEConfigurationViewController.h" 9 | #import "Gossip.h" 10 | #import "GSECodecsViewController.h" 11 | #import "GSEMenuViewController.h" 12 | 13 | 14 | @interface GSEConfigurationViewController () @end 15 | 16 | 17 | @implementation GSEConfigurationViewController { 18 | UITableView *_tableView; 19 | NSArray *_testAccounts; 20 | } 21 | 22 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 23 | if (self = [super initWithNibName:nil bundle:nil]) { 24 | _testAccounts = nil; 25 | [self loadTestAccounts]; 26 | } 27 | return self; 28 | } 29 | 30 | - (void)loadTestAccounts { 31 | NSMutableArray *accounts = [NSMutableArray arrayWithCapacity:2]; 32 | 33 | GSAccountConfiguration *account = [GSAccountConfiguration defaultConfiguration]; 34 | account.address = @"chakrit@getonsip.com"; 35 | account.username = @"getonsip_chakrit"; 36 | account.password = @"3WLDiLdLaUQiA5rr"; 37 | account.domain = @"getonsip.com"; 38 | account.proxyServer = @"sip.onsip.com"; 39 | [accounts addObject:account]; 40 | 41 | account = [account copy]; 42 | account.address = @"chakrit2@getonsip.com"; 43 | account.username = @"getonsip_chakrit2"; 44 | account.password = @"RsbRokgpDZcbmuBT"; 45 | [accounts addObject:account]; 46 | 47 | account = [GSAccountConfiguration defaultConfiguration]; 48 | account.address = @"chakrit@sip2sip.info"; 49 | account.username = @"chakrit"; 50 | account.password = @"tyixr52w9k"; 51 | account.domain = @"sip2sip.info"; 52 | account.authRealm = @"sip2sip.info"; 53 | account.proxyServer = @"proxy.sipthor.net"; 54 | [accounts addObject:account]; 55 | 56 | account = [GSAccountConfiguration defaultConfiguration]; 57 | account.address = @"1664470@sipgate.co.uk"; 58 | account.username = @"1664470"; 59 | account.password = @"N34TYU8M"; 60 | account.domain = @"sipgate.co.uk"; 61 | account.proxyServer = @"sipgate.co.uk"; 62 | [accounts addObject:account]; 63 | 64 | _testAccounts = [NSArray arrayWithArray:accounts]; 65 | } 66 | 67 | - (void)dealloc { 68 | _testAccounts = nil; 69 | } 70 | 71 | 72 | - (NSString *)title { 73 | return @"Account"; 74 | } 75 | 76 | 77 | - (void)loadView { 78 | CGRect frame = [[UIScreen mainScreen] bounds]; 79 | 80 | _tableView = [UITableView alloc]; 81 | _tableView = [_tableView initWithFrame:frame style:UITableViewStylePlain]; 82 | [_tableView setDelegate:self]; 83 | [_tableView setDataSource:self]; 84 | 85 | UIView *container = [[UIView alloc] init]; 86 | [container setFrame:frame]; 87 | [container addSubview:_tableView]; 88 | [self setView:container]; 89 | } 90 | 91 | - (void)viewDidAppear:(BOOL)animated { 92 | [_tableView deselectRowAtIndexPath:[_tableView indexPathForSelectedRow] animated:YES]; 93 | } 94 | 95 | 96 | - (void)userDidSelectAccount:(GSAccountConfiguration *)accountConfig { 97 | GSConfiguration *configuration = [GSConfiguration defaultConfiguration]; 98 | configuration.account = accountConfig; 99 | configuration.logLevel = 3; 100 | configuration.consoleLogLevel = 3; 101 | 102 | GSUserAgent *agent = [GSUserAgent sharedAgent]; 103 | [agent configure:configuration]; 104 | [agent start]; 105 | 106 | GSEMenuViewController *menu = [[GSEMenuViewController alloc] init]; 107 | menu.account = agent.account; // only one account supported, for now. 108 | [[self navigationController] pushViewController:menu animated:YES]; 109 | } 110 | 111 | 112 | #pragma mark - UITableViewDatasource && UITableViewDelegate 113 | 114 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 115 | return 1; 116 | } 117 | 118 | - (NSInteger)tableView:(UITableView *)tableView 119 | numberOfRowsInSection:(NSInteger)section { 120 | return [_testAccounts count]; 121 | } 122 | 123 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 124 | static NSString *const kCellId = @"sip_account"; 125 | 126 | NSInteger row = [indexPath row]; 127 | if (row < 0 || row == [_testAccounts count]) 128 | return nil; 129 | 130 | // build table cell 131 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; 132 | if (!cell) { 133 | cell = [UITableViewCell alloc]; 134 | cell = [cell initWithStyle:UITableViewCellStyleDefault 135 | reuseIdentifier:kCellId]; 136 | } 137 | 138 | GSAccountConfiguration *account = [_testAccounts objectAtIndex:row]; 139 | [[cell textLabel] setText:account.address]; 140 | 141 | return cell; 142 | } 143 | 144 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 145 | NSInteger row = [indexPath row]; 146 | if (row < 0 || row == [_testAccounts count]) 147 | return; 148 | 149 | GSAccountConfiguration *account = [_testAccounts objectAtIndex:row]; 150 | [self userDidSelectAccount:account]; 151 | } 152 | 153 | @end 154 | -------------------------------------------------------------------------------- /GossipExample/GSEMenuViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSEMenuViewController.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import "Gossip.h" 9 | 10 | 11 | @interface GSEMenuViewController : UIViewController 12 | 13 | @property (nonatomic, strong) GSAccount *account; 14 | 15 | @property (nonatomic, strong) IBOutlet UILabel *statusLabel; 16 | @property (nonatomic, strong) IBOutlet UIButton *connectButton; 17 | @property (nonatomic, strong) IBOutlet UIButton *disconnectButton; 18 | @property (nonatomic, strong) IBOutlet UIButton *makeCallButton; 19 | 20 | - (IBAction)userDidTapCodecs; 21 | - (IBAction)userDidTapUseG729; 22 | 23 | - (IBAction)userDidTapConnect; 24 | - (IBAction)userDidTapDisconnect; 25 | - (IBAction)userDidTapMakeCall; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /GossipExample/GSEMenuViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSEMenuViewController.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import "GSEMenuViewController.h" 9 | #import "Gossip.h" 10 | #import "GSECallInitController.h" 11 | #import "GSECallViewController.h" 12 | #import "GSECodecsViewController.h" 13 | 14 | 15 | @interface GSEMenuViewController () @end 16 | 17 | 18 | @implementation GSEMenuViewController { 19 | GSECallInitController *_callInit; 20 | GSCall *_incomingCall; 21 | } 22 | 23 | @synthesize account = _account; 24 | 25 | @synthesize statusLabel = _statusLabel; 26 | @synthesize connectButton = _connectButton; 27 | @synthesize disconnectButton = _disconnectButton; 28 | @synthesize makeCallButton = _makeCallButton; 29 | 30 | 31 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 32 | if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 33 | _account = nil; 34 | _callInit = nil; 35 | _incomingCall = nil; 36 | } 37 | return self; 38 | } 39 | 40 | - (void)dealloc { 41 | [_account removeObserver:self forKeyPath:@"status"]; 42 | _account = nil; 43 | 44 | _callInit = nil; 45 | _incomingCall = nil; 46 | 47 | _statusLabel = nil; 48 | _connectButton = nil; 49 | _disconnectButton = nil; 50 | _makeCallButton = nil; 51 | } 52 | 53 | 54 | - (NSString *)title { 55 | return @"Menu"; 56 | } 57 | 58 | - (void)setAccount:(GSAccount *)account { 59 | [self willChangeValueForKey:@"account"]; 60 | [_account removeObserver:self forKeyPath:@"status"]; 61 | _account = account; 62 | _account.delegate = self; 63 | [_account addObserver:self 64 | forKeyPath:@"status" 65 | options:NSKeyValueObservingOptionInitial 66 | context:nil]; 67 | [self didChangeValueForKey:@"account"]; 68 | } 69 | 70 | 71 | - (void)viewDidLoad { 72 | [[self navigationItem] setHidesBackButton:YES]; 73 | [_account addObserver:self 74 | forKeyPath:@"status" 75 | options:NSKeyValueObservingOptionInitial 76 | context:nil]; 77 | } 78 | 79 | 80 | - (void)userDidTapCodecs { 81 | GSECodecsViewController *controller = [GSECodecsViewController alloc]; 82 | controller = [controller init]; 83 | 84 | [[self navigationController] pushViewController:controller animated:YES]; 85 | } 86 | 87 | - (void)userDidTapUseG729 { 88 | GSUserAgent *agent = [GSUserAgent sharedAgent]; 89 | NSArray *codecs = [agent arrayOfAvailableCodecs]; 90 | for (GSCodecInfo *codec in codecs) { 91 | if (![codec.codecId hasPrefix:@"G729"]) { 92 | NSLog(@"Disabling: %@", codec.codecId); 93 | [codec disable]; 94 | } else { 95 | NSLog(@"Maximizing: %@", codec.codecId); 96 | [codec setPriority:254]; 97 | } 98 | } 99 | } 100 | 101 | 102 | - (IBAction)userDidTapConnect { 103 | [_account connect]; 104 | } 105 | 106 | - (IBAction)userDidTapDisconnect { 107 | [_account disconnect]; 108 | } 109 | 110 | - (IBAction)userDidTapSwitchAccount:(id)sender { 111 | [[GSUserAgent sharedAgent] reset]; 112 | [self.navigationController popToRootViewControllerAnimated:YES]; 113 | } 114 | 115 | 116 | - (IBAction)userDidTapMakeCall { 117 | if (!_callInit) { 118 | _callInit = [[GSECallInitController alloc] init]; 119 | _callInit.navigationController = [self navigationController]; 120 | } 121 | 122 | [_callInit makeNewCall]; 123 | } 124 | 125 | 126 | - (void)userDidPickupCall { 127 | GSECallViewController *controller = [[GSECallViewController alloc] init]; 128 | controller.call = _incomingCall; 129 | 130 | [[self navigationController] pushViewController:controller animated:YES]; 131 | } 132 | 133 | - (void)userDidDenyCall { 134 | [_incomingCall end]; 135 | _incomingCall = nil; 136 | } 137 | 138 | 139 | - (void)statusDidChange { 140 | switch (_account.status) { 141 | case GSAccountStatusOffline: { 142 | [_statusLabel setText:@"Offline."]; 143 | [_connectButton setEnabled:YES]; 144 | [_disconnectButton setEnabled:NO]; 145 | [_makeCallButton setEnabled:NO]; 146 | } break; 147 | 148 | case GSAccountStatusConnecting: { 149 | [_statusLabel setText:@"Connecting..."]; 150 | [_connectButton setEnabled:NO]; 151 | [_disconnectButton setEnabled:NO]; 152 | [_makeCallButton setEnabled:NO]; 153 | } break; 154 | 155 | case GSAccountStatusConnected: { 156 | [_statusLabel setText:@"Connected."]; 157 | [_connectButton setEnabled:NO]; 158 | [_disconnectButton setEnabled:YES]; 159 | [_makeCallButton setEnabled:YES]; 160 | } break; 161 | 162 | case GSAccountStatusDisconnecting: { 163 | [_statusLabel setText:@"Disconnecting..."]; 164 | [_connectButton setEnabled:NO]; 165 | [_disconnectButton setEnabled:NO]; 166 | [_makeCallButton setEnabled:NO]; 167 | } break; 168 | 169 | case GSAccountStatusInvalid: { 170 | [_statusLabel setText:@"Invalid account info."]; 171 | [_connectButton setEnabled:YES]; 172 | [_disconnectButton setEnabled:NO]; 173 | [_makeCallButton setEnabled:NO]; 174 | } break; 175 | } 176 | } 177 | 178 | 179 | #pragma mark - GSAccountDelegate 180 | 181 | - (void)account:(GSAccount *)account didReceiveIncomingCall:(GSCall *)call { 182 | _incomingCall = call; 183 | 184 | UIAlertView *alert = [[UIAlertView alloc] init]; 185 | [alert setAlertViewStyle:UIAlertViewStyleDefault]; 186 | [alert setDelegate:self]; 187 | [alert setTitle:@"Incoming call."]; 188 | [alert addButtonWithTitle:@"Deny"]; 189 | [alert addButtonWithTitle:@"Answer"]; 190 | [alert setCancelButtonIndex:0]; 191 | [alert show]; 192 | } 193 | 194 | 195 | #pragma mark - UIAlertViewDelegate 196 | 197 | - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { 198 | if (buttonIndex == [alertView cancelButtonIndex]) { 199 | [self userDidDenyCall]; 200 | } else { 201 | [self userDidPickupCall]; 202 | } 203 | } 204 | 205 | 206 | #pragma mark - KVO 207 | 208 | - (void)observeValueForKeyPath:(NSString *)keyPath 209 | ofObject:(id)object 210 | change:(NSDictionary *)change 211 | context:(void *)context { 212 | if ([keyPath isEqualToString:@"status"]) 213 | [self statusDidChange]; 214 | } 215 | 216 | @end 217 | -------------------------------------------------------------------------------- /GossipExample/GSEMenuViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1552 5 | 12E55 6 | 3084 7 | 1187.39 8 | 626.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 2083 12 | 13 | 14 | IBProxyObject 15 | IBUIButton 16 | IBUILabel 17 | IBUIView 18 | 19 | 20 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 21 | 22 | 23 | PluginDependencyRecalculationVersion 24 | 25 | 26 | 27 | 28 | IBFilesOwner 29 | IBCocoaTouchFramework 30 | 31 | 32 | IBFirstResponder 33 | IBCocoaTouchFramework 34 | 35 | 36 | 37 | 274 38 | 39 | 40 | 41 | 292 42 | {{20, 20}, {280, 21}} 43 | 44 | 45 | 46 | _NS:9 47 | NO 48 | YES 49 | 7 50 | NO 51 | IBCocoaTouchFramework 52 | (status) 53 | 54 | 1 55 | MCAwIDAAA 56 | darkTextColor 57 | 58 | 59 | 0 60 | 10 61 | 62 | 1 63 | 17 64 | 65 | 66 | Helvetica 67 | 17 68 | 16 69 | 70 | 71 | 72 | 73 | 292 74 | {{20, 359}, {280, 37}} 75 | 76 | 77 | 78 | _NS:9 79 | NO 80 | IBCocoaTouchFramework 81 | 0 82 | 0 83 | 1 84 | Make a call 85 | 86 | 3 87 | MQA 88 | 89 | 90 | 1 91 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 92 | 93 | 94 | 3 95 | MC41AA 96 | 97 | 98 | 2 99 | 15 100 | 101 | 102 | Helvetica-Bold 103 | 15 104 | 16 105 | 106 | 107 | 108 | 109 | 292 110 | {{20, 271}, {280, 37}} 111 | 112 | 113 | 114 | _NS:9 115 | NO 116 | IBCocoaTouchFramework 117 | NO 118 | 0 119 | 0 120 | 1 121 | Disconnect 122 | 123 | 124 | 1 125 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 292 134 | {{20, 226}, {280, 37}} 135 | 136 | 137 | 138 | _NS:9 139 | NO 140 | IBCocoaTouchFramework 141 | 0 142 | 0 143 | 1 144 | Connect 145 | 146 | 147 | 1 148 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 292 157 | {{20, 134}, {280, 37}} 158 | 159 | 160 | 161 | _NS:9 162 | NO 163 | IBCocoaTouchFramework 164 | 0 165 | 0 166 | 1 167 | Codecs 168 | 169 | 170 | 1 171 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 292 180 | {{20, 89}, {280, 37}} 181 | 182 | 183 | 184 | _NS:9 185 | NO 186 | IBCocoaTouchFramework 187 | 0 188 | 0 189 | 1 190 | Use G729 191 | 192 | 193 | 1 194 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 292 203 | {{20, 315}, {280, 37}} 204 | 205 | 206 | 207 | _NS:9 208 | NO 209 | IBCocoaTouchFramework 210 | 0 211 | 0 212 | 1 213 | Disconnect & Switch Account 214 | 215 | 216 | 1 217 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 218 | 219 | 220 | 221 | 222 | 223 | 224 | {{0, 64}, {320, 416}} 225 | 226 | 227 | 228 | 229 | 3 230 | MQA 231 | 232 | 2 233 | 234 | 235 | 236 | 237 | NO 238 | 239 | IBCocoaTouchFramework 240 | 241 | 242 | 243 | 244 | 245 | 246 | view 247 | 248 | 249 | 250 | 7 251 | 252 | 253 | 254 | connectButton 255 | 256 | 257 | 258 | 15 259 | 260 | 261 | 262 | disconnectButton 263 | 264 | 265 | 266 | 16 267 | 268 | 269 | 270 | makeCallButton 271 | 272 | 273 | 274 | 17 275 | 276 | 277 | 278 | statusLabel 279 | 280 | 281 | 282 | 8 283 | 284 | 285 | 286 | userDidTapMakeCall 287 | 288 | 289 | 7 290 | 291 | 14 292 | 293 | 294 | 295 | userDidTapDisconnect 296 | 297 | 298 | 7 299 | 300 | 13 301 | 302 | 303 | 304 | userDidTapConnect 305 | 306 | 307 | 7 308 | 309 | 12 310 | 311 | 312 | 313 | userDidTapCodecs 314 | 315 | 316 | 7 317 | 318 | 28 319 | 320 | 321 | 322 | userDidTapUseG729 323 | 324 | 325 | 7 326 | 327 | 30 328 | 329 | 330 | 331 | userDidTapSwitchAccount: 332 | 333 | 334 | 7 335 | 336 | 34 337 | 338 | 339 | 340 | 341 | 342 | 0 343 | 344 | 345 | 346 | 347 | 348 | 1 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | -1 363 | 364 | 365 | File's Owner 366 | 367 | 368 | -2 369 | 370 | 371 | 372 | 373 | 9 374 | 375 | 376 | 377 | 378 | 10 379 | 380 | 381 | 382 | 383 | 11 384 | 385 | 386 | 387 | 388 | 18 389 | 390 | 391 | 392 | 393 | 5 394 | 395 | 396 | 397 | 398 | 29 399 | 400 | 401 | 402 | 403 | 31 404 | 405 | 406 | 407 | 408 | 409 | 410 | GSEMenuViewController 411 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 412 | UIResponder 413 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 414 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 415 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 416 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 417 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 418 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 419 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 420 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 421 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 422 | 423 | 424 | 425 | 426 | 427 | 36 428 | 429 | 430 | 431 | 432 | GSEMenuViewController 433 | UIViewController 434 | 435 | id 436 | id 437 | id 438 | id 439 | id 440 | id 441 | 442 | 443 | 444 | userDidTapCodecs 445 | id 446 | 447 | 448 | userDidTapConnect 449 | id 450 | 451 | 452 | userDidTapDisconnect 453 | id 454 | 455 | 456 | userDidTapMakeCall 457 | id 458 | 459 | 460 | userDidTapSwitchAccount: 461 | id 462 | 463 | 464 | userDidTapUseG729 465 | id 466 | 467 | 468 | 469 | UIButton 470 | UIButton 471 | UIButton 472 | UILabel 473 | 474 | 475 | 476 | connectButton 477 | UIButton 478 | 479 | 480 | disconnectButton 481 | UIButton 482 | 483 | 484 | makeCallButton 485 | UIButton 486 | 487 | 488 | statusLabel 489 | UILabel 490 | 491 | 492 | 493 | IBProjectSource 494 | ./Classes/GSEMenuViewController.h 495 | 496 | 497 | 498 | 499 | 0 500 | IBCocoaTouchFramework 501 | 502 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 503 | 504 | 505 | YES 506 | 3 507 | 2083 508 | 509 | 510 | -------------------------------------------------------------------------------- /GossipExample/GSERootViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GSERootViewController.h 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | 9 | @interface GSERootViewController : UIViewController 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /GossipExample/GSERootViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GSERootViewController.m 3 | // Gossip 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import "GSERootViewController.h" 9 | #import "GSEConfigurationViewController.h" 10 | 11 | 12 | @interface GSERootViewController () @end 13 | 14 | 15 | @implementation GSERootViewController { 16 | UINavigationController *_nav; 17 | } 18 | 19 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 20 | if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 21 | GSEConfigurationViewController *root = nil; 22 | root = [[GSEConfigurationViewController alloc] init]; 23 | 24 | _nav = [[UINavigationController alloc] initWithRootViewController:root]; 25 | [_nav setDelegate:self]; 26 | } 27 | return self; 28 | } 29 | 30 | - (void)dealloc { 31 | _nav = nil; 32 | } 33 | 34 | 35 | - (void)viewDidLoad { 36 | [self addChildViewController:_nav]; 37 | [[self view] addSubview:[_nav view]]; 38 | } 39 | 40 | 41 | // nothing to do for UINavigationController yet. 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /GossipExample/GossipExample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | net.chakrit.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /GossipExample/GossipExample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'GSGossipExample' target in the 'GSGossipExample' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_3_0 8 | #warning "This project uses features only available in iOS SDK 3.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #import 15 | #endif 16 | -------------------------------------------------------------------------------- /GossipExample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /GossipExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // GSGossipExample 4 | // 5 | // Created by Chakrit Wichian on 7/6/12. 6 | // 7 | 8 | #import 9 | 10 | #import "GSEAppDelegate.h" 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | @autoreleasepool { 15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([GSEAppDelegate class])); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /GossipExample/ringtone.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/GossipExample/ringtone.wav -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # LICENSE 2 | 3 | This is free and unencumbered software released into the public domain. 4 | 5 | Anyone is free to copy, modify, publish, use, compile, sell, or 6 | distribute this software, either in source code form or as a compiled 7 | binary, for any purpose, commercial or non-commercial, and by any 8 | means. 9 | 10 | In jurisdictions that recognize copyright laws, the author or authors 11 | of this software dedicate any and all copyright interest in the 12 | software to the public domain. We make this dedication for the benefit 13 | of the public at large and to the detriment of our heirs and 14 | successors. We intend this dedication to be an overt act of 15 | relinquishment in perpetuity of all present and future rights to this 16 | software under copyright law. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | For more information, please refer to <[http://unlicense.org/](http://unlicense.org/)> 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GOSSIP 2 | 3 | An Objective-C convenience wrapper around the PJSIP client library. In addition to that, 4 | the GOSSIP repository also contains: 5 | 6 | * [PJSIP][0] - Original source mirror as git submodule so we can track commits that GOSSIP 7 | will compile against. 8 | 9 | * Utility script for compiling PJSIP - This automates the process described by the 10 | [Getting Started - iPhone][2] guide on the PJSIP website. 11 | 12 | * Pre-built fat PJSIP binaries - These run on armv7, armv7s, arm64 and i386 out of the 13 | box. You can also build each architecture individually by yourself using the 14 | aforementioned script. 15 | 16 | # USAGE 17 | 18 | 1. Clone the GOSSIP sources. 19 | 2. Make sure to also clone PJSIP submodule as we need the PJSIP headers. 20 | 3. (optional) Use the provided script to build your custom version of PJSIP. 21 | 4. Adds the GOSSIP xcodeproj as reference to your main application project. Either 22 | workspace reference or as a subproject should works. 23 | 5. Initializes `GSUserAgent` on application starts. 24 | 25 | Check the [GSUserAgent documentation][5] for further instructions. 26 | 27 | Example of a successful `git clone` command: 28 | 29 | ```bash 30 | git clone git://github.com/chakrit/gossip.git 31 | cd gossip 32 | git submodule init 33 | git submodule update --recursive 34 | ``` 35 | 36 | I can add support for CocoaPods if there is demand. I have opted not to work on this 37 | just yet due to the need to reference PJSIP headers (which in turn has a lot of 38 | architecture-specific macro `#ifdefs` that sometimes break badly.) 39 | 40 | # BUILD PJSIPs 41 | 42 | Before GOSSIP will build, you must first have a working PJSIP binary either by: 43 | 44 | * Using the pre-built binaries already available in this repository. In which case, you 45 | should not need to do anything. 46 | * Use the `gossip/pjsip/pjsip` script to build a version of PJSIP that suit your needs. 47 | 48 | For example, to create a new build for `arm64`, try the following: 49 | 50 | ```sh 51 | $ cd gossip 52 | $ cd pjsip 53 | $ ./pjsip arm64 54 | $ ./pjsip info arm64 55 | ``` 56 | 57 | Or to create new fat binaries on your machine, try the following: 58 | 59 | ```sh 60 | cd gossip 61 | cd pjsip 62 | ./pjsip all 63 | ./pjsip info . 64 | ``` 65 | 66 | # LICENSE 67 | 68 | We do not own the license nor the copyright of the PJSIP source code and derivatives which 69 | are required for GOSSIP to function. Check the 70 | [PJSIP licensing][1] page for more information. 71 | 72 | Otherwise the Gossip codebase is public domain. See the [LICENSE.md](LICENSE.md) file for 73 | the full details. 74 | 75 | # SUPPORT 76 | 77 | Please file a [new GitHub issue][3]. I am also available at service [at] chakrit.net or 78 | over Twitter as [@chakrit][4]. 79 | 80 | # CONTRIBUTORS 81 | 82 | ``` 83 | 144 Chakrit Wichian 84 | 5 Hlung 85 | 1 Thane Brimhall 86 | ``` 87 | 88 | 89 | [0]: http://www.pjsip.org/ 90 | [1]: http://www.pjsip.org/licensing.htm 91 | [2]: https://trac.pjsip.org/repos/wiki/Getting-Started/iPhone 92 | [3]: https://github.com/chakrit/gossip/issues/new 93 | [4]: http://twitter.com/chakrit 94 | [5]: http://gh.chakrit.net/gossip/interface_g_s_user_agent.html 95 | -------------------------------------------------------------------------------- /gen-docs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | doxygen .doxygen 4 | open docs/index.html 5 | -------------------------------------------------------------------------------- /gossip.podspec: -------------------------------------------------------------------------------- 1 | # vim: filetype=ruby 2 | # 3 | # Be sure to run `pod spec lint gossip.podspec' to ensure this is a 4 | # valid spec and remove all comments before submitting the spec. 5 | # 6 | # To learn more about the attributes see http://docs.cocoapods.org/specification.html 7 | # 8 | Pod::Spec.new do |s| 9 | s.name = "gossip" 10 | s.version = "0.1.1" 11 | s.summary = "A SIP client library that wraps PJSIP into a nice and clean OO api." 12 | s.homepage = "https://github.com/chakrit/gossip" 13 | s.license = { :type => 'Public Domain', :file => 'LICENSE.md' } 14 | s.author = { "Chakrit Wichian" => "service@chakrit.net" } 15 | s.source = { :git => "https://github.com/chakrit/gossip.git", :tag => "v0.1.1" } 16 | s.platform = :ios, '6.0' 17 | 18 | s.source_files = 'Gossip', 'Gossip/**/*.{h,m}' 19 | s.resource = "GossipExample/ringtone.wav" 20 | 21 | s.frameworks = 'AudioToolbox', 'AVFoundation', 'CFNetwork', 'CoreMedia', 'CoreVideo', 'CoreAudio', 'Foundation' 22 | # Specify a list of libraries that the application needs to link 23 | # against for this Pod to work. 24 | # 25 | # s.library = 'iconv' 26 | # s.libraries = 'iconv', 'xml2' 27 | s.libraries = 28 | "libg7221codec-arm-apple-darwin9.a", 29 | "libgsmcodec-arm-apple-darwin9.a", 30 | "libilbccodec-arm-apple-darwin9.a", 31 | "libmilenage-arm-apple-darwin9.a", 32 | "libpj-arm-apple-darwin9.a", 33 | "libpjlib-util-arm-apple-darwin9.a", 34 | "libpjmedia-arm-apple-darwin9.a", 35 | "libpjmedia-audiodev-arm-apple-darwin9.a", 36 | "libpjmedia-codec-arm-apple-darwin9.a", 37 | "libpjmedia-videodev-arm-apple-darwin9.a", 38 | "libpjnath-arm-apple-darwin9.a", 39 | "libpjsdp-arm-apple-darwin9.a", 40 | "libpjsip-arm-apple-darwin9.a", 41 | "libpjsip-simple-arm-apple-darwin9.a", 42 | "libpjsip-ua-arm-apple-darwin9.a", 43 | "libpjsua-arm-apple-darwin9.a", 44 | "libresample-arm-apple-darwin9.a", 45 | "libspeex-arm-apple-darwin9.a", 46 | "libsrtp-arm-apple-darwin9.a" 47 | 48 | s.requires_arc = true 49 | 50 | s.xcconfig = { 51 | 'HEADER_SEARCH_PATHS' => [ 52 | "$(SRCROOT)/pjsip/src/pjlib/include", 53 | "$(SRCROOT)/pjsip/src/pjlib-util/include", 54 | "$(SRCROOT)/pjsip/src/pjmedia/include", 55 | "$(SRCROOT)/pjsip/src/pjnath/include", 56 | "$(SRCROOT)/pjsip/src/pjsip/include", 57 | "$(SRCROOT)/pjsip/src/third_party/resample/include", 58 | "$(SRCROOT)/pjsip/src/third_party/speex/include", 59 | "$(SRCROOT)/pjsip/src/third_party/srtp/crypto/include", 60 | "$(SRCROOT)/pjsip/src/third_party/srtp/include", 61 | ].join(' '), 62 | 'LIBRARY_SEARCH_PATHS' => [ 63 | "$(inherited)", 64 | "$(SRCROOT)/pjsip/lib", 65 | "$(SRCROOT)/pjsip", 66 | "$(SRCROOT)/pjsip/source/third_party/lib", 67 | ].join(' '), 68 | } 69 | end 70 | -------------------------------------------------------------------------------- /pjsip/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | -------------------------------------------------------------------------------- /pjsip/config_site.h: -------------------------------------------------------------------------------- 1 | #define PJ_CONFIG_IPHONE 1 2 | #include 3 | 4 | // enable G729 5 | #define PJMEDIA_HAS_G729_CODEC 1 6 | 7 | -------------------------------------------------------------------------------- /pjsip/lib/arm64/libg7221codec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libg7221codec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libgsmcodec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libgsmcodec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libilbccodec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libilbccodec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libpj-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libpj-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libpjlib-util-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libpjlib-util-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libpjmedia-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libpjmedia-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libpjmedia-audiodev-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libpjmedia-audiodev-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libpjmedia-codec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libpjmedia-codec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libpjmedia-videodev-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libpjmedia-videodev-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libpjnath-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libpjnath-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libpjsdp-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libpjsdp-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libpjsip-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libpjsip-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libpjsip-simple-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libpjsip-simple-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libpjsip-ua-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libpjsip-ua-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libpjsua-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libpjsua-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libpjsua2-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libpjsua2-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libresample-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libresample-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libspeex-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libspeex-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/arm64/libsrtp-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/arm64/libsrtp-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libg7221codec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libg7221codec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libgsmcodec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libgsmcodec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libilbccodec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libilbccodec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libpj-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libpj-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libpjlib-util-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libpjlib-util-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libpjmedia-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libpjmedia-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libpjmedia-audiodev-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libpjmedia-audiodev-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libpjmedia-codec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libpjmedia-codec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libpjmedia-videodev-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libpjmedia-videodev-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libpjnath-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libpjnath-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libpjsdp-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libpjsdp-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libpjsip-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libpjsip-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libpjsip-simple-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libpjsip-simple-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libpjsip-ua-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libpjsip-ua-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libpjsua-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libpjsua-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libpjsua2-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libpjsua2-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libresample-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libresample-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libspeex-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libspeex-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv6/libsrtp-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv6/libsrtp-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libg7221codec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libg7221codec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libgsmcodec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libgsmcodec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libilbccodec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libilbccodec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libpj-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libpj-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libpjlib-util-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libpjlib-util-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libpjmedia-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libpjmedia-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libpjmedia-audiodev-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libpjmedia-audiodev-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libpjmedia-codec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libpjmedia-codec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libpjmedia-videodev-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libpjmedia-videodev-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libpjnath-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libpjnath-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libpjsdp-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libpjsdp-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libpjsip-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libpjsip-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libpjsip-simple-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libpjsip-simple-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libpjsip-ua-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libpjsip-ua-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libpjsua-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libpjsua-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libpjsua2-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libpjsua2-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libresample-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libresample-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libspeex-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libspeex-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7/libsrtp-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7/libsrtp-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libg7221codec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libg7221codec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libgsmcodec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libgsmcodec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libilbccodec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libilbccodec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libpj-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libpj-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libpjlib-util-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libpjlib-util-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libpjmedia-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libpjmedia-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libpjmedia-audiodev-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libpjmedia-audiodev-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libpjmedia-codec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libpjmedia-codec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libpjmedia-videodev-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libpjmedia-videodev-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libpjnath-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libpjnath-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libpjsdp-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libpjsdp-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libpjsip-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libpjsip-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libpjsip-simple-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libpjsip-simple-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libpjsip-ua-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libpjsip-ua-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libpjsua-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libpjsua-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libpjsua2-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libpjsua2-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libresample-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libresample-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libspeex-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libspeex-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/armv7s/libsrtp-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/armv7s/libsrtp-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libg7221codec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libg7221codec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libgsmcodec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libgsmcodec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libilbccodec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libilbccodec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libpj-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libpj-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libpjlib-util-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libpjlib-util-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libpjmedia-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libpjmedia-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libpjmedia-audiodev-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libpjmedia-audiodev-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libpjmedia-codec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libpjmedia-codec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libpjmedia-videodev-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libpjmedia-videodev-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libpjnath-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libpjnath-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libpjsdp-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libpjsdp-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libpjsip-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libpjsip-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libpjsip-simple-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libpjsip-simple-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libpjsip-ua-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libpjsip-ua-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libpjsua-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libpjsua-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libpjsua2-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libpjsua2-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libresample-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libresample-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libspeex-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libspeex-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/i386/libsrtp-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/i386/libsrtp-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libg7221codec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libg7221codec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libgsmcodec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libgsmcodec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libilbccodec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libilbccodec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libpj-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libpj-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libpjlib-util-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libpjlib-util-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libpjmedia-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libpjmedia-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libpjmedia-audiodev-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libpjmedia-audiodev-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libpjmedia-codec-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libpjmedia-codec-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libpjmedia-videodev-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libpjmedia-videodev-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libpjnath-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libpjnath-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libpjsdp-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libpjsdp-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libpjsip-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libpjsip-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libpjsip-simple-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libpjsip-simple-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libpjsip-ua-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libpjsip-ua-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libpjsua-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libpjsua-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libpjsua2-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libpjsua2-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libresample-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libresample-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libspeex-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libspeex-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/lib/libsrtp-arm-apple-darwin9.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chakrit/gossip/3b509b3a6cb9f9dfc6f3dbb2d844469c7c319477/pjsip/lib/libsrtp-arm-apple-darwin9.a -------------------------------------------------------------------------------- /pjsip/pjsip: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd `dirname $BASH_SOURCE` 4 | export BASE_DIR=`pwd -P` 5 | 6 | set -o errexit 7 | set -o errtrace 8 | 9 | export PRE=" ───── " 10 | 11 | 12 | function help() { 13 | cat < "$BASE_DIR"/clean.log 43 | } 44 | 45 | 46 | function info() { 47 | echo "$PRE ARCH" 48 | find lib/$1/*.a | \ 49 | xargs lipo -info 2>/dev/null | grep "rchitecture" | \ 50 | sed -El "s/^.+\: .+\/(.+) (are|is architecture)\: (.+)$/\\3 - \\1/g" | \ 51 | sort 52 | 53 | echo 54 | echo "$PRE INCLUDES" 55 | find src | grep "\\include$" | sort 56 | } 57 | 58 | 59 | function armv7() { _build "armv7"; } 60 | function armv7s() { _build "armv7s"; } 61 | function arm64() { _build "arm64"; } 62 | 63 | function i386() { 64 | export DEVPATH=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer 65 | export CFLAGS="-O2 -m32 -mios-simulator-version-min=5.0" 66 | export LDFLAGS="-O2 -m32 -mios-simulator-version-min=5.0" 67 | _build "i386" 68 | } 69 | 70 | function all() { 71 | armv7 && echo && armv7s && echo && arm64 && echo && i386 72 | echo 73 | _merge 74 | } 75 | 76 | 77 | function _build() { 78 | echo "$PRE BUILD" 79 | echo "building for $1. this may take a while, tail -f $1.log to see progress." 80 | echo "" 81 | 82 | cd "$BASE_DIR"/src 83 | cp "$BASE_DIR"/config_site.h "$BASE_DIR"/src/pjlib/include/pj 84 | ARCH="-arch $1" ./configure-iphone 2>&1 > "$BASE_DIR"/$1.log 85 | 86 | make dep 2>&1 >> "$BASE_DIR"/$1.log 87 | make clean 2>&1 >> "$BASE_DIR"/$1.log 88 | make 2>&1 >> "$BASE_DIR"/$1.log 89 | 90 | echo 91 | _collect $1 92 | } 93 | 94 | function _collect() { 95 | echo "$PRE COLLECT" 96 | cd "$BASE_DIR" 97 | mkdir -p lib/$1 98 | 99 | for x in `find src | grep "\.a$"`; do 100 | cp -v ./$x ./lib/$1 101 | done | tee "$BASE_DIR"/collect.log 102 | } 103 | 104 | function _merge() { 105 | echo "$PRE MERGE" 106 | cd "$BASE_DIR" 107 | 108 | for lib in `find lib/i386/*.a`; do 109 | lipo -arch armv7 lib/armv7/${lib##*/} \ 110 | -arch armv7s lib/armv7s/${lib##*/} \ 111 | -arch arm64 lib/arm64/${lib##*/} \ 112 | -arch i386 lib/i386/${lib##*/} \ 113 | -create -output lib/${lib##*/} 114 | done | tee "$BASE_DIR"/merge.log 115 | } 116 | 117 | 118 | if [ -n "$1" ]; then 119 | CMD=$1 120 | shift 121 | $CMD $* 122 | 123 | echo 124 | echo "$PRE DONE" 125 | 126 | else 127 | help 128 | fi 129 | 130 | --------------------------------------------------------------------------------