~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.2.1/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java

  • Committer: Package Import Robot
  • Author(s): Francois Marier, Francois Marier, Mark Purcell
  • Date: 2014-10-18 15:08:50 UTC
  • mfrom: (1.1.12)
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20141018150850-2exfk34ckb15pcwi
Tags: 1.4.1-0.1
[ Francois Marier ]
* Non-maintainer upload
* New upstream release (closes: #759576, #741130)
  - debian/rules +PJPROJECT_VERSION := 2.2.1
  - add upstream patch to fix broken TLS support
  - add patch to fix pjproject regression

[ Mark Purcell ]
* Build-Depends:
  - sflphone-daemon + libavformat-dev, libavcodec-dev, libswscale-dev,
  libavdevice-dev, libavutil-dev
  - sflphone-gnome + libclutter-gtk-1.0-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: MyApp.java 4734 2014-02-05 09:32:57Z nanang $ */
 
2
/*
 
3
 * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 */
 
19
package org.pjsip.pjsua2.app;
 
20
 
 
21
import java.io.File;
 
22
import java.util.ArrayList;
 
23
import org.pjsip.pjsua2.*;
 
24
 
 
25
 
 
26
/* Interface to separate UI & engine a bit better */
 
27
interface MyAppObserver {
 
28
        abstract void notifyRegState(pjsip_status_code code, String reason, int expiration);
 
29
        abstract void notifyIncomingCall(MyCall call);
 
30
        abstract void notifyCallState(MyCall call);
 
31
        abstract void notifyBuddyState(MyBuddy buddy);
 
32
}
 
33
 
 
34
 
 
35
class MyLogWriter extends LogWriter {
 
36
        @Override
 
37
        public void write(LogEntry entry) {
 
38
                System.out.println(entry.getMsg());
 
39
        }
 
40
}
 
41
 
 
42
 
 
43
class MyCall extends Call {
 
44
        MyCall(MyAccount acc, int call_id) {
 
45
                super(acc, call_id);
 
46
        }
 
47
 
 
48
        @Override
 
49
        public void onCallState(OnCallStateParam prm) {
 
50
                MyApp.observer.notifyCallState(this);
 
51
        }
 
52
        
 
53
        @Override
 
54
        public void onCallMediaState(OnCallMediaStateParam prm) {
 
55
                CallInfo ci;
 
56
                try {
 
57
                        ci = getInfo();
 
58
                } catch (Exception e) {
 
59
                        return;
 
60
                }
 
61
                
 
62
                CallMediaInfoVector cmiv = ci.getMedia();
 
63
                
 
64
                for (int i = 0; i < cmiv.size(); i++) {
 
65
                        CallMediaInfo cmi = cmiv.get(i);
 
66
                        if (cmi.getType() == pjmedia_type.PJMEDIA_TYPE_AUDIO &&
 
67
                            (cmi.getStatus() == pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE ||
 
68
                             cmi.getStatus() == pjsua_call_media_status.PJSUA_CALL_MEDIA_REMOTE_HOLD))
 
69
                        {
 
70
                                // unfortunately, on Java too, the returned Media cannot be downcasted to AudioMedia 
 
71
                                Media m = getMedia(i);
 
72
                                AudioMedia am = AudioMedia.typecastFromMedia(m);
 
73
                                
 
74
                                // connect ports
 
75
                                try {
 
76
                                        MyApp.ep.audDevManager().getCaptureDevMedia().startTransmit(am);
 
77
                                        am.startTransmit(MyApp.ep.audDevManager().getPlaybackDevMedia());
 
78
                                } catch (Exception e) {
 
79
                                        continue;
 
80
                                }
 
81
                        }
 
82
                }
 
83
        }
 
84
}
 
85
 
 
86
 
 
87
class MyAccount extends Account {
 
88
        public ArrayList<MyBuddy> buddyList = new ArrayList<MyBuddy>();
 
89
        public AccountConfig cfg;
 
90
        
 
91
        MyAccount(AccountConfig config) {
 
92
                super();
 
93
                cfg = config;
 
94
        }
 
95
        
 
96
        public MyBuddy addBuddy(BuddyConfig bud_cfg)
 
97
        {
 
98
                /* Create Buddy */
 
99
                MyBuddy bud = new MyBuddy(bud_cfg);
 
100
                try {
 
101
                        bud.create(this, bud_cfg);
 
102
                } catch (Exception e) {
 
103
                        bud = null;
 
104
                }
 
105
                
 
106
                if (bud != null) {
 
107
                        buddyList.add(bud);
 
108
                        if (bud_cfg.getSubscribe())
 
109
                                try {
 
110
                                        bud.subscribePresence(true);
 
111
                                } catch (Exception e) {}
 
112
                }
 
113
                
 
114
                return bud;
 
115
        }
 
116
        
 
117
        public void delBuddy(MyBuddy buddy) {
 
118
                buddyList.remove(buddy);
 
119
        }
 
120
        
 
121
        public void delBuddy(int index) {
 
122
                buddyList.remove(index);
 
123
        }
 
124
        
 
125
        @Override
 
126
        public void onRegState(OnRegStateParam prm) {
 
127
                MyApp.observer.notifyRegState(prm.getCode(), prm.getReason(), prm.getExpiration());
 
128
        }
 
129
 
 
130
        @Override
 
131
        public void onIncomingCall(OnIncomingCallParam prm) {
 
132
                System.out.println("======== Incoming call ======== ");
 
133
                MyCall call = new MyCall(this, prm.getCallId());
 
134
                MyApp.observer.notifyIncomingCall(call);
 
135
        }
 
136
        
 
137
        @Override
 
138
        public void onInstantMessage(OnInstantMessageParam prm) {
 
139
                System.out.println("======== Incoming pager ======== ");
 
140
                System.out.println("From                : " + prm.getFromUri());
 
141
                System.out.println("To                  : " + prm.getToUri());
 
142
                System.out.println("Contact             : " + prm.getContactUri());
 
143
                System.out.println("Mimetype    : " + prm.getContentType());
 
144
                System.out.println("Body                : " + prm.getMsgBody());
 
145
        }
 
146
}
 
147
 
 
148
 
 
149
class MyBuddy extends Buddy {
 
150
        public BuddyConfig cfg;
 
151
        
 
152
        MyBuddy(BuddyConfig config) {
 
153
                super();
 
154
                cfg = config;
 
155
        }
 
156
        
 
157
        String getStatusText() {
 
158
                BuddyInfo bi;
 
159
                
 
160
                try {
 
161
                        bi = getInfo();
 
162
                } catch (Exception e) {
 
163
                        return "?";
 
164
                }
 
165
                
 
166
                String status = "";
 
167
                if (bi.getSubState() == pjsip_evsub_state.PJSIP_EVSUB_STATE_ACTIVE) {
 
168
                        if (bi.getPresStatus().getStatus() == pjsua_buddy_status.PJSUA_BUDDY_STATUS_ONLINE) {
 
169
                                status = bi.getPresStatus().getStatusText();
 
170
                                if (status == null || status.isEmpty()) {
 
171
                                        status = "Online";
 
172
                                }
 
173
                        } else if (bi.getPresStatus().getStatus() == pjsua_buddy_status.PJSUA_BUDDY_STATUS_OFFLINE) {
 
174
                                status = "Offline";
 
175
                        } else {
 
176
                                status = "Unknown";
 
177
                        }
 
178
                }
 
179
                return status;
 
180
        }
 
181
 
 
182
        @Override
 
183
        public void onBuddyState() {
 
184
                MyApp.observer.notifyBuddyState(this);
 
185
        }
 
186
        
 
187
}
 
188
 
 
189
 
 
190
class MyAccountConfig {
 
191
        public AccountConfig accCfg = new AccountConfig();
 
192
        public ArrayList<BuddyConfig> buddyCfgs = new ArrayList<BuddyConfig>();
 
193
        
 
194
        public void readObject(ContainerNode node) {
 
195
                try {
 
196
                        ContainerNode acc_node = node.readContainer("Account");
 
197
                        accCfg.readObject(acc_node);
 
198
                        ContainerNode buddies_node = acc_node.readArray("buddies");
 
199
                        buddyCfgs.clear();
 
200
                        while (buddies_node.hasUnread()) {
 
201
                                BuddyConfig bud_cfg = new BuddyConfig(); 
 
202
                                bud_cfg.readObject(buddies_node);
 
203
                                buddyCfgs.add(bud_cfg);
 
204
                        }
 
205
                } catch (Exception e) {}
 
206
        }
 
207
        
 
208
        public void writeObject(ContainerNode node) {
 
209
                try {
 
210
                        ContainerNode acc_node = node.writeNewContainer("Account");
 
211
                        accCfg.writeObject(acc_node);
 
212
                        ContainerNode buddies_node = acc_node.writeNewArray("buddies");
 
213
                        for (int j = 0; j < buddyCfgs.size(); j++) {
 
214
                                buddyCfgs.get(j).writeObject(buddies_node);
 
215
                        }
 
216
                } catch (Exception e) {}
 
217
        }
 
218
}
 
219
 
 
220
 
 
221
class MyApp {
 
222
        static {
 
223
                System.loadLibrary("pjsua2");
 
224
                System.out.println("Library loaded");
 
225
        }
 
226
        
 
227
        public static Endpoint ep = new Endpoint();
 
228
        public static MyAppObserver observer;
 
229
        public ArrayList<MyAccount> accList = new ArrayList<MyAccount>();
 
230
 
 
231
        private ArrayList<MyAccountConfig> accCfgs = new ArrayList<MyAccountConfig>();
 
232
        private EpConfig epConfig = new EpConfig();
 
233
        private TransportConfig sipTpConfig = new TransportConfig();
 
234
        private String appDir;
 
235
        
 
236
        /* Maintain reference to log writer to avoid premature cleanup by GC */
 
237
        private MyLogWriter logWriter;
 
238
 
 
239
        private final String configName = "pjsua2.json";
 
240
        private final int SIP_PORT  = 6000;
 
241
        private final int LOG_LEVEL = 4;
 
242
        
 
243
        public void init(MyAppObserver obs, String app_dir) {
 
244
                init(obs, app_dir, false);
 
245
        }
 
246
        
 
247
        public void init(MyAppObserver obs, String app_dir, boolean own_worker_thread) {
 
248
                observer = obs;
 
249
                appDir = app_dir;
 
250
                
 
251
                /* Create endpoint */
 
252
                try {
 
253
                        ep.libCreate();
 
254
                } catch (Exception e) {
 
255
                        return;
 
256
                }
 
257
                        
 
258
                
 
259
                /* Load config */
 
260
                String configPath = appDir + "/" + configName;
 
261
                File f = new File(configPath);
 
262
                if (f.exists()) {
 
263
                        loadConfig(configPath);
 
264
                } else {
 
265
                        /* Set 'default' values */
 
266
                        sipTpConfig.setPort(SIP_PORT);
 
267
                }
 
268
                
 
269
                /* Override log level setting */
 
270
                epConfig.getLogConfig().setLevel(LOG_LEVEL);
 
271
                epConfig.getLogConfig().setConsoleLevel(LOG_LEVEL);
 
272
                
 
273
                /* Set log config. */
 
274
                LogConfig log_cfg = epConfig.getLogConfig();
 
275
                logWriter = new MyLogWriter();
 
276
                log_cfg.setWriter(logWriter);
 
277
                log_cfg.setDecor(log_cfg.getDecor() & 
 
278
                                                 ~(pj_log_decoration.PJ_LOG_HAS_CR.swigValue() | 
 
279
                                                   pj_log_decoration.PJ_LOG_HAS_NEWLINE.swigValue()));
 
280
                
 
281
                /* Set ua config. */
 
282
                UaConfig ua_cfg = epConfig.getUaConfig();
 
283
                ua_cfg.setUserAgent("Pjsua2 Android " + ep.libVersion().getFull());
 
284
                StringVector stun_servers = new StringVector();
 
285
                stun_servers.add("stun.pjsip.org");
 
286
                ua_cfg.setStunServer(stun_servers);
 
287
                if (own_worker_thread) {
 
288
                        ua_cfg.setThreadCnt(0);
 
289
                        ua_cfg.setMainThreadOnly(true);
 
290
                }
 
291
                
 
292
                /* Init endpoint */
 
293
                try {
 
294
                        ep.libInit(epConfig);
 
295
                } catch (Exception e) {
 
296
                        return;
 
297
                }
 
298
                
 
299
                /* Create transports. */
 
300
                try {
 
301
                        ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_UDP, sipTpConfig);
 
302
                } catch (Exception e) {
 
303
                        System.out.println(e);
 
304
                }
 
305
 
 
306
                try {
 
307
                        ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_TCP, sipTpConfig);
 
308
                } catch (Exception e) {
 
309
                        System.out.println(e);
 
310
                }
 
311
                
 
312
                /* Create accounts. */
 
313
                for (int i = 0; i < accCfgs.size(); i++) {
 
314
                        MyAccountConfig my_cfg = accCfgs.get(i);
 
315
                        MyAccount acc = addAcc(my_cfg.accCfg);
 
316
                        if (acc == null)
 
317
                                continue;
 
318
                        
 
319
                        /* Add Buddies */
 
320
                        for (int j = 0; j < my_cfg.buddyCfgs.size(); j++) {
 
321
                                BuddyConfig bud_cfg = my_cfg.buddyCfgs.get(j);
 
322
                                acc.addBuddy(bud_cfg);
 
323
                        }
 
324
                }
 
325
 
 
326
                /* Start. */
 
327
                try {
 
328
                        ep.libStart();
 
329
                } catch (Exception e) {
 
330
                        return;
 
331
                }
 
332
        }
 
333
        
 
334
        public MyAccount addAcc(AccountConfig cfg) {
 
335
                MyAccount acc = new MyAccount(cfg);
 
336
                try {
 
337
                        acc.create(cfg);
 
338
                } catch (Exception e) {
 
339
                        acc = null;
 
340
                        return null;
 
341
                }
 
342
                
 
343
                accList.add(acc);
 
344
                return acc;
 
345
        }
 
346
        
 
347
        public void delAcc(MyAccount acc) {
 
348
                accList.remove(acc);
 
349
        }
 
350
        
 
351
        private void loadConfig(String filename) {
 
352
                JsonDocument json = new JsonDocument();
 
353
                
 
354
                try {
 
355
                        /* Load file */
 
356
                        json.loadFile(filename);
 
357
                        ContainerNode root = json.getRootContainer();
 
358
                        
 
359
                        /* Read endpoint config */
 
360
                        epConfig.readObject(root);
 
361
                        
 
362
                        /* Read transport config */
 
363
                        ContainerNode tp_node = root.readContainer("SipTransport");
 
364
                        sipTpConfig.readObject(tp_node);
 
365
                        
 
366
                        /* Read account configs */
 
367
                        accCfgs.clear();
 
368
                        ContainerNode accs_node = root.readArray("accounts");
 
369
                        while (accs_node.hasUnread()) {
 
370
                                MyAccountConfig acc_cfg = new MyAccountConfig();
 
371
                                acc_cfg.readObject(accs_node);
 
372
                                accCfgs.add(acc_cfg);
 
373
                        }
 
374
                } catch (Exception e) {
 
375
                        System.out.println(e);
 
376
                }
 
377
                
 
378
                /* Force delete json now, as I found that Java somehow destroys it
 
379
                 * after lib has been destroyed and from non-registered thread.
 
380
                 */
 
381
                json.delete();
 
382
        }
 
383
 
 
384
        private void buildAccConfigs() {
 
385
                /* Sync accCfgs from accList */
 
386
                accCfgs.clear();
 
387
                for (int i = 0; i < accList.size(); i++) {
 
388
                        MyAccount acc = accList.get(i);
 
389
                        MyAccountConfig my_acc_cfg = new MyAccountConfig();
 
390
                        my_acc_cfg.accCfg = acc.cfg;
 
391
                        
 
392
                        my_acc_cfg.buddyCfgs.clear();
 
393
                        for (int j = 0; j < acc.buddyList.size(); j++) {
 
394
                                MyBuddy bud = acc.buddyList.get(j);
 
395
                                my_acc_cfg.buddyCfgs.add(bud.cfg);
 
396
                        }
 
397
                        
 
398
                        accCfgs.add(my_acc_cfg);
 
399
                }
 
400
        }
 
401
        
 
402
        private void saveConfig(String filename) {
 
403
                JsonDocument json = new JsonDocument();
 
404
                
 
405
                try {
 
406
                        /* Write endpoint config */
 
407
                        json.writeObject(epConfig);
 
408
                        
 
409
                        /* Write transport config */
 
410
                        ContainerNode tp_node = json.writeNewContainer("SipTransport");
 
411
                        sipTpConfig.writeObject(tp_node);
 
412
                        
 
413
                        /* Write account configs */
 
414
                        buildAccConfigs();
 
415
                        ContainerNode accs_node = json.writeNewArray("accounts");
 
416
                        for (int i = 0; i < accCfgs.size(); i++) {
 
417
                                accCfgs.get(i).writeObject(accs_node);
 
418
                        }
 
419
                        
 
420
                        /* Save file */
 
421
                        json.saveFile(filename);
 
422
                } catch (Exception e) {}
 
423
 
 
424
                /* Force delete json now, as I found that Java somehow destroys it
 
425
                 * after lib has been destroyed and from non-registered thread.
 
426
                 */
 
427
                json.delete();
 
428
        }
 
429
        
 
430
        public void deinit() {
 
431
                String configPath = appDir + "/" + configName;
 
432
                saveConfig(configPath);
 
433
                
 
434
                /* Try force GC to avoid late destroy of PJ objects as they should be
 
435
                 * deleted before lib is destroyed.
 
436
                 */
 
437
                Runtime.getRuntime().gc();
 
438
                
 
439
                /* Shutdown pjsua. Note that Endpoint destructor will also invoke
 
440
                 * libDestroy(), so this will be a test of double libDestroy().
 
441
                 */
 
442
                try {
 
443
                        ep.libDestroy();
 
444
                } catch (Exception e) {}
 
445
                
 
446
                /* Force delete Endpoint here, to avoid deletion from a non-
 
447
                 * registered thread (by GC?). 
 
448
                 */
 
449
                ep.delete();
 
450
                ep = null;
 
451
        } 
 
452
}