├── .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 |
13 |
14 | IBUIButton
15 | IBUIView
16 | IBUILabel
17 | IBProxyObject
18 |
19 |
20 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
21 |
22 |
26 |
27 |
31 |
35 |
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 |
--------------------------------------------------------------------------------