PageRenderTime 62ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/src/org/sipdroid/sipua/SipdroidEngine.java

https://github.com/sortir/sipdroid
Java | 606 lines | 496 code | 76 blank | 34 comment | 164 complexity | 91584f9d3b3e60c2b145504487c1b5cf MD5 | raw file
Possible License(s): GPL-3.0, BSD-3-Clause
  1. /*
  2. * Copyright (C) 2009 The Sipdroid Open Source Project
  3. * Copyright (C) 2008 Hughes Systique Corporation, USA (http://www.hsc.com)
  4. *
  5. * This file is part of Sipdroid (http://www.sipdroid.org)
  6. *
  7. * Sipdroid is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This source code is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this source code; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. package org.sipdroid.sipua;
  22. import java.io.IOException;
  23. import java.net.UnknownHostException;
  24. import org.sipdroid.net.KeepAliveSip;
  25. import org.sipdroid.sipua.ui.ChangeAccount;
  26. import org.sipdroid.sipua.ui.Logger;
  27. import org.sipdroid.sipua.ui.LoopAlarm;
  28. import org.sipdroid.sipua.ui.Receiver;
  29. import org.sipdroid.sipua.ui.Settings;
  30. import org.sipdroid.sipua.ui.Sipdroid;
  31. import org.zoolu.net.IpAddress;
  32. import org.zoolu.net.SocketAddress;
  33. import org.zoolu.sip.address.NameAddress;
  34. import org.zoolu.sip.provider.SipProvider;
  35. import org.zoolu.sip.provider.SipStack;
  36. import android.content.Context;
  37. import android.content.SharedPreferences.Editor;
  38. import android.net.Uri;
  39. import android.net.wifi.WifiManager;
  40. import android.os.Build;
  41. import android.os.PowerManager;
  42. import android.os.SystemClock;
  43. import android.preference.PreferenceManager;
  44. public class SipdroidEngine implements RegisterAgentListener {
  45. public static final int LINES = 2;
  46. public int pref;
  47. public static final int UNINITIALIZED = 0x0;
  48. public static final int INITIALIZED = 0x2;
  49. /** User Agent */
  50. public UserAgent[] uas;
  51. public UserAgent ua;
  52. /** Register Agent */
  53. public RegisterAgent[] ras;
  54. private KeepAliveSip[] kas;
  55. /** UserAgentProfile */
  56. public UserAgentProfile[] user_profiles;
  57. public SipProvider[] sip_providers;
  58. public static PowerManager.WakeLock[] wl,pwl;
  59. UserAgentProfile getUserAgentProfile(String suffix) {
  60. UserAgentProfile user_profile = new UserAgentProfile(null);
  61. user_profile.username = PreferenceManager.getDefaultSharedPreferences(getUIContext()).getString(Settings.PREF_USERNAME+suffix, Settings.DEFAULT_USERNAME); // modified
  62. user_profile.passwd = PreferenceManager.getDefaultSharedPreferences(getUIContext()).getString(Settings.PREF_PASSWORD+suffix, Settings.DEFAULT_PASSWORD);
  63. if (PreferenceManager.getDefaultSharedPreferences(getUIContext()).getString(Settings.PREF_DOMAIN+suffix, Settings.DEFAULT_DOMAIN).length() == 0) {
  64. user_profile.realm = PreferenceManager.getDefaultSharedPreferences(getUIContext()).getString(Settings.PREF_SERVER+suffix, Settings.DEFAULT_SERVER);
  65. } else {
  66. user_profile.realm = PreferenceManager.getDefaultSharedPreferences(getUIContext()).getString(Settings.PREF_DOMAIN+suffix, Settings.DEFAULT_DOMAIN);
  67. }
  68. user_profile.realm_orig = user_profile.realm;
  69. if (PreferenceManager.getDefaultSharedPreferences(getUIContext()).getString(Settings.PREF_FROMUSER+suffix, Settings.DEFAULT_FROMUSER).length() == 0) {
  70. user_profile.from_url = user_profile.username;
  71. } else {
  72. user_profile.from_url = PreferenceManager.getDefaultSharedPreferences(getUIContext()).getString(Settings.PREF_FROMUSER+suffix, Settings.DEFAULT_FROMUSER);
  73. }
  74. // MMTel configuration (added by mandrajg)
  75. user_profile.qvalue = PreferenceManager.getDefaultSharedPreferences(getUIContext()).getString(Settings.PREF_MMTEL_QVALUE, Settings.DEFAULT_MMTEL_QVALUE);
  76. user_profile.mmtel = PreferenceManager.getDefaultSharedPreferences(getUIContext()).getBoolean(Settings.PREF_MMTEL, Settings.DEFAULT_MMTEL);
  77. user_profile.pub = PreferenceManager.getDefaultSharedPreferences(getUIContext()).getBoolean(Settings.PREF_EDGE+suffix, Settings.DEFAULT_EDGE) ||
  78. PreferenceManager.getDefaultSharedPreferences(getUIContext()).getBoolean(Settings.PREF_3G+suffix, Settings.DEFAULT_3G);
  79. return user_profile;
  80. }
  81. public boolean StartEngine() {
  82. PowerManager pm = (PowerManager) getUIContext().getSystemService(Context.POWER_SERVICE);
  83. if (wl == null) {
  84. if (!PreferenceManager.getDefaultSharedPreferences(getUIContext()).contains(org.sipdroid.sipua.ui.Settings.PREF_KEEPON)) {
  85. Editor edit = PreferenceManager.getDefaultSharedPreferences(getUIContext()).edit();
  86. edit.putBoolean(org.sipdroid.sipua.ui.Settings.PREF_KEEPON, Build.MODEL.equals("Nexus One") ||
  87. Build.MODEL.equals("Nexus S") ||
  88. Build.MODEL.equals("Archos5") ||
  89. Build.MODEL.equals("ADR6300") ||
  90. Build.MODEL.equals("PC36100") ||
  91. Build.MODEL.equals("HTC Desire") ||
  92. Build.MODEL.equals("HTC Incredible S") ||
  93. Build.MODEL.equals("HTC Wildfire") ||
  94. Build.MODEL.equals("GT-I9100"));
  95. edit.commit();
  96. }
  97. wl = new PowerManager.WakeLock[LINES];
  98. pwl = new PowerManager.WakeLock[LINES];
  99. }
  100. pref = ChangeAccount.getPref(Receiver.mContext);
  101. uas = new UserAgent[LINES];
  102. ras = new RegisterAgent[LINES];
  103. kas = new KeepAliveSip[LINES];
  104. lastmsgs = new String[LINES];
  105. sip_providers = new SipProvider[LINES];
  106. user_profiles = new UserAgentProfile[LINES];
  107. user_profiles[0] = getUserAgentProfile("");
  108. for (int i = 1; i < LINES; i++)
  109. user_profiles[1] = getUserAgentProfile(""+i);
  110. SipStack.init(null);
  111. int i = 0;
  112. for (UserAgentProfile user_profile : user_profiles) {
  113. if (wl[i] == null) {
  114. wl[i] = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Sipdroid.SipdroidEngine");
  115. if (PreferenceManager.getDefaultSharedPreferences(getUIContext()).getBoolean(org.sipdroid.sipua.ui.Settings.PREF_KEEPON, org.sipdroid.sipua.ui.Settings.DEFAULT_KEEPON))
  116. pwl[i] = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "Sipdroid.SipdroidEngine");
  117. }
  118. try {
  119. SipStack.debug_level = 0;
  120. // SipStack.log_path = "/data/data/org.sipdroid.sipua";
  121. SipStack.max_retransmission_timeout = 4000;
  122. SipStack.default_transport_protocols = new String[1];
  123. SipStack.default_transport_protocols[0] = PreferenceManager.getDefaultSharedPreferences(getUIContext()).getString(Settings.PREF_PROTOCOL+(i!=0?i:""),
  124. user_profile.realm.equals(Settings.DEFAULT_SERVER)?"tcp":"udp");
  125. String version = "Sipdroid/" + Sipdroid.getVersion() + "/" + Build.MODEL;
  126. SipStack.ua_info = version;
  127. SipStack.server_info = version;
  128. IpAddress.setLocalIpAddress();
  129. sip_providers[i] = new SipProvider(IpAddress.localIpAddress, 0);
  130. user_profile.contact_url = getContactURL(user_profile.username,sip_providers[i]);
  131. if (user_profile.from_url.indexOf("@") < 0) {
  132. user_profile.from_url +=
  133. "@"
  134. + user_profile.realm;
  135. }
  136. CheckEngine();
  137. // added by mandrajg
  138. String icsi = null;
  139. if (user_profile.mmtel == true){
  140. icsi = "\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"";
  141. }
  142. uas[i] = ua = new UserAgent(sip_providers[i], user_profile);
  143. ras[i] = new RegisterAgent(sip_providers[i], user_profile.from_url, // modified
  144. user_profile.contact_url, user_profile.username,
  145. user_profile.realm, user_profile.passwd, this, user_profile,
  146. user_profile.qvalue, icsi, user_profile.pub); // added by mandrajg
  147. kas[i] = new KeepAliveSip(sip_providers[i],100000);
  148. } catch (Exception E) {
  149. }
  150. i++;
  151. }
  152. register();
  153. listen();
  154. return true;
  155. }
  156. private String getContactURL(String username,SipProvider sip_provider) {
  157. int i = username.indexOf("@");
  158. if (i != -1) {
  159. // if the username already contains a @
  160. //strip it and everthing following it
  161. username = username.substring(0, i);
  162. }
  163. return username + "@" + IpAddress.localIpAddress
  164. + (sip_provider.getPort() != 0?":"+sip_provider.getPort():"")
  165. + ";transport=" + sip_provider.getDefaultTransport();
  166. }
  167. void setOutboundProxy(SipProvider sip_provider,int i) {
  168. try {
  169. if (sip_provider != null) sip_provider.setOutboundProxy(new SocketAddress(
  170. IpAddress.getByName(PreferenceManager.getDefaultSharedPreferences(getUIContext()).getString(Settings.PREF_DNS+i, Settings.DEFAULT_DNS)),
  171. Integer.valueOf(PreferenceManager.getDefaultSharedPreferences(getUIContext()).getString(Settings.PREF_PORT+(i!=0?i:""), Settings.DEFAULT_PORT))));
  172. } catch (Exception e) {
  173. }
  174. }
  175. public void CheckEngine() {
  176. int i = 0;
  177. for (SipProvider sip_provider : sip_providers) {
  178. if (sip_provider != null && !sip_provider.hasOutboundProxy())
  179. setOutboundProxy(sip_provider,i);
  180. i++;
  181. }
  182. }
  183. public Context getUIContext() {
  184. return Receiver.mContext;
  185. }
  186. public int getRemoteVideo() {
  187. // Logger.d("ua.remote_video_port = " + ua.remote_video_port);
  188. return ua.remote_video_port;
  189. }
  190. public int getLocalVideo() {
  191. // Logger.d("ua.local_video_port = " + ua.local_video_port);
  192. return ua.local_video_port;
  193. }
  194. public String getRemoteAddr() {
  195. // Logger.d("ua.remote_media_address = " + ua.remote_media_address);
  196. return ua.remote_media_address;
  197. }
  198. public void expire() {
  199. Receiver.expire_time = 0;
  200. int i = 0;
  201. for (RegisterAgent ra : ras) {
  202. if (ra != null && ra.CurrentState == RegisterAgent.REGISTERED) {
  203. ra.CurrentState = RegisterAgent.UNREGISTERED;
  204. Receiver.onText(Receiver.REGISTER_NOTIFICATION+i, null, 0, 0);
  205. }
  206. i++;
  207. }
  208. register();
  209. }
  210. public void unregister(int i) {
  211. if (user_profiles[i] == null || user_profiles[i].username.equals("") ||
  212. user_profiles[i].realm.equals("")) return;
  213. RegisterAgent ra = ras[i];
  214. if (ra != null && ra.unregister()) {
  215. Receiver.alarm(0, LoopAlarm.class);
  216. Receiver.onText(Receiver.REGISTER_NOTIFICATION+i,getUIContext().getString(R.string.reg),R.drawable.sym_presence_idle,0);
  217. wl[i].acquire();
  218. } else
  219. Receiver.onText(Receiver.REGISTER_NOTIFICATION+i, null, 0, 0);
  220. }
  221. public void registerMore() {
  222. IpAddress.setLocalIpAddress();
  223. int i = 0;
  224. for (RegisterAgent ra : ras) {
  225. try {
  226. if (user_profiles[i] == null || user_profiles[i].username.equals("") ||
  227. user_profiles[i].realm.equals("")) {
  228. i++;
  229. continue;
  230. }
  231. user_profiles[i].contact_url = getContactURL(user_profiles[i].from_url,sip_providers[i]);
  232. if (ra != null && !ra.isRegistered() && Receiver.isFast(i) && ra.register()) {
  233. Receiver.onText(Receiver.REGISTER_NOTIFICATION+i,getUIContext().getString(R.string.reg),R.drawable.sym_presence_idle,0);
  234. wl[i].acquire();
  235. }
  236. } catch (Exception ex) {
  237. }
  238. i++;
  239. }
  240. }
  241. public void register() {
  242. IpAddress.setLocalIpAddress();
  243. int i = 0;
  244. for (RegisterAgent ra : ras) {
  245. try {
  246. if (user_profiles[i] == null || user_profiles[i].username.equals("") ||
  247. user_profiles[i].realm.equals("")) {
  248. i++;
  249. continue;
  250. }
  251. user_profiles[i].contact_url = getContactURL(user_profiles[i].from_url,sip_providers[i]);
  252. if (!Receiver.isFast(i)) {
  253. unregister(i);
  254. } else {
  255. if (ra != null && ra.register()) {
  256. Receiver.onText(Receiver.REGISTER_NOTIFICATION+i,getUIContext().getString(R.string.reg),R.drawable.sym_presence_idle,0);
  257. wl[i].acquire();
  258. }
  259. }
  260. } catch (Exception ex) {
  261. }
  262. i++;
  263. }
  264. }
  265. public void registerUdp() {
  266. IpAddress.setLocalIpAddress();
  267. int i = 0;
  268. for (RegisterAgent ra : ras) {
  269. try {
  270. if (user_profiles[i] == null || user_profiles[i].username.equals("") ||
  271. user_profiles[i].realm.equals("") ||
  272. sip_providers[i] == null ||
  273. sip_providers[i].getDefaultTransport() == null ||
  274. sip_providers[i].getDefaultTransport().equals("tcp")) {
  275. i++;
  276. continue;
  277. }
  278. user_profiles[i].contact_url = getContactURL(user_profiles[i].from_url,sip_providers[i]);
  279. if (!Receiver.isFast(i)) {
  280. unregister(i);
  281. } else {
  282. if (ra != null && ra.register()) {
  283. Receiver.onText(Receiver.REGISTER_NOTIFICATION+i,getUIContext().getString(R.string.reg),R.drawable.sym_presence_idle,0);
  284. wl[i].acquire();
  285. }
  286. }
  287. } catch (Exception ex) {
  288. }
  289. i++;
  290. }
  291. }
  292. public void halt() { // modified
  293. long time = SystemClock.elapsedRealtime();
  294. int i = 0;
  295. for (RegisterAgent ra : ras) {
  296. unregister(i);
  297. while (ra != null && ra.CurrentState != RegisterAgent.UNREGISTERED && SystemClock.elapsedRealtime()-time < 2000)
  298. try {
  299. Thread.sleep(100);
  300. } catch (InterruptedException e1) {
  301. }
  302. if (wl[i].isHeld()) {
  303. wl[i].release();
  304. if (pwl[i] != null && pwl[i].isHeld()) pwl[i].release();
  305. }
  306. if (kas[i] != null) {
  307. Receiver.alarm(0, LoopAlarm.class);
  308. kas[i].halt();
  309. }
  310. Receiver.onText(Receiver.REGISTER_NOTIFICATION+i, null, 0, 0);
  311. if (ra != null)
  312. ra.halt();
  313. if (uas[i] != null)
  314. uas[i].hangup();
  315. if (sip_providers[i] != null)
  316. sip_providers[i].halt();
  317. i++;
  318. }
  319. }
  320. public boolean isRegistered()
  321. {
  322. for (RegisterAgent ra : ras)
  323. if (ra != null && ra.isRegistered())
  324. return true;
  325. return false;
  326. }
  327. public boolean isRegistered(int i)
  328. {
  329. if (ras[i] == null)
  330. {
  331. return false;
  332. }
  333. return ras[i].isRegistered();
  334. }
  335. public void onUaRegistrationSuccess(RegisterAgent reg_ra, NameAddress target,
  336. NameAddress contact, String result) {
  337. int i = 0;
  338. for (RegisterAgent ra : ras) {
  339. if (ra == reg_ra) break;
  340. i++;
  341. }
  342. if (isRegistered(i)) {
  343. if (Receiver.on_wlan)
  344. Receiver.alarm(60, LoopAlarm.class);
  345. Receiver.onText(Receiver.REGISTER_NOTIFICATION+i,getUIContext().getString(i == pref?R.string.regpref:R.string.regclick),R.drawable.sym_presence_available,0);
  346. reg_ra.subattempts = 0;
  347. reg_ra.startMWI();
  348. Receiver.registered();
  349. } else
  350. Receiver.onText(Receiver.REGISTER_NOTIFICATION+i, null, 0,0);
  351. if (wl[i].isHeld()) {
  352. wl[i].release();
  353. if (pwl[i] != null && pwl[i].isHeld()) pwl[i].release();
  354. }
  355. }
  356. String[] lastmsgs;
  357. public void onMWIUpdate(RegisterAgent mwi_ra, boolean voicemail, int number, String vmacc) {
  358. int i = 0;
  359. for (RegisterAgent ra : ras) {
  360. if (ra == mwi_ra) break;
  361. i++;
  362. }
  363. if (i != pref) return;
  364. if (voicemail) {
  365. String msgs = getUIContext().getString(R.string.voicemail);
  366. if (number != 0) {
  367. msgs = msgs + ": " + number;
  368. }
  369. Receiver.MWI_account = vmacc;
  370. if (lastmsgs[i] == null || !msgs.equals(lastmsgs[i])) {
  371. Receiver.onText(Receiver.MWI_NOTIFICATION, msgs,android.R.drawable.stat_notify_voicemail,0);
  372. lastmsgs[i] = msgs;
  373. }
  374. } else {
  375. Receiver.onText(Receiver.MWI_NOTIFICATION, null, 0,0);
  376. lastmsgs[i] = null;
  377. }
  378. }
  379. static long lasthalt,lastpwl;
  380. /** When a UA failed on (un)registering. */
  381. public void onUaRegistrationFailure(RegisterAgent reg_ra, NameAddress target,
  382. NameAddress contact, String result) {
  383. boolean retry = false;
  384. int i = 0;
  385. for (RegisterAgent ra : ras) {
  386. if (ra == reg_ra) break;
  387. i++;
  388. }
  389. if (isRegistered(i)) {
  390. reg_ra.CurrentState = RegisterAgent.UNREGISTERED;
  391. Receiver.onText(Receiver.REGISTER_NOTIFICATION+i, null, 0, 0);
  392. } else {
  393. retry = true;
  394. Receiver.onText(Receiver.REGISTER_NOTIFICATION+i,getUIContext().getString(R.string.regfailed)+" ("+result+")",R.drawable.sym_presence_away,0);
  395. }
  396. if (retry && SystemClock.uptimeMillis() > lastpwl + 45000 && pwl[i] != null && !pwl[i].isHeld() && Receiver.on_wlan) {
  397. lastpwl = SystemClock.uptimeMillis();
  398. if (wl[i].isHeld())
  399. wl[i].release();
  400. pwl[i].acquire();
  401. register();
  402. if (!wl[i].isHeld() && pwl[i].isHeld()) pwl[i].release();
  403. } else if (wl[i].isHeld()) {
  404. wl[i].release();
  405. if (pwl[i] != null && pwl[i].isHeld()) pwl[i].release();
  406. }
  407. if (SystemClock.uptimeMillis() > lasthalt + 45000) {
  408. lasthalt = SystemClock.uptimeMillis();
  409. sip_providers[i].haltConnections();
  410. }
  411. if (!Thread.currentThread().getName().equals("main"))
  412. updateDNS();
  413. reg_ra.stopMWI();
  414. WifiManager wm = (WifiManager) Receiver.mContext.getSystemService(Context.WIFI_SERVICE);
  415. wm.startScan();
  416. }
  417. public void updateDNS() {
  418. Editor edit = PreferenceManager.getDefaultSharedPreferences(getUIContext()).edit();
  419. int i = 0;
  420. for (SipProvider sip_provider : sip_providers) {
  421. try {
  422. edit.putString(Settings.PREF_DNS+i, IpAddress.getByName(PreferenceManager.getDefaultSharedPreferences(getUIContext()).getString(Settings.PREF_SERVER+(i!=0?i:""), "")).toString());
  423. } catch (UnknownHostException e1) {
  424. i++;
  425. continue;
  426. }
  427. edit.commit();
  428. setOutboundProxy(sip_provider,i);
  429. i++;
  430. }
  431. }
  432. /** Receives incoming calls (auto accept) */
  433. public void listen()
  434. {
  435. for (UserAgent ua : uas) {
  436. if (ua != null) {
  437. ua.printLog("UAS: WAITING FOR INCOMING CALL");
  438. if (!ua.user_profile.audio && !ua.user_profile.video)
  439. {
  440. ua.printLog("ONLY SIGNALING, NO MEDIA");
  441. }
  442. ua.listen();
  443. }
  444. }
  445. }
  446. public void info(char c, int duration) {
  447. ua.info(c, duration);
  448. }
  449. /** Makes a new call */
  450. public boolean call(String target_url,boolean force) {
  451. int p = pref;
  452. boolean found = false;
  453. if (isRegistered(p) && Receiver.isFast(p))
  454. found = true;
  455. else {
  456. for (p = 0; p < LINES; p++)
  457. if (isRegistered(p) && Receiver.isFast(p)) {
  458. found = true;
  459. break;
  460. }
  461. if (!found && force) {
  462. p = pref;
  463. if (Receiver.isFast(p))
  464. found = true;
  465. else for (p = 0; p < LINES; p++)
  466. if (Receiver.isFast(p)) {
  467. found = true;
  468. break;
  469. }
  470. }
  471. }
  472. if (!found || (ua = uas[p]) == null) {
  473. if (PreferenceManager.getDefaultSharedPreferences(getUIContext()).getBoolean(Settings.PREF_CALLBACK, Settings.DEFAULT_CALLBACK) &&
  474. PreferenceManager.getDefaultSharedPreferences(getUIContext()).getString(Settings.PREF_POSURL, Settings.DEFAULT_POSURL).length() > 0) {
  475. Receiver.url("n="+Uri.decode(target_url));
  476. return true;
  477. }
  478. return false;
  479. }
  480. ua.printLog("UAC: CALLING " + target_url);
  481. if (!ua.user_profile.audio && !ua.user_profile.video)
  482. {
  483. ua.printLog("ONLY SIGNALING, NO MEDIA");
  484. }
  485. return ua.call(target_url, false);
  486. }
  487. public void answercall()
  488. {
  489. Receiver.stopRingtone();
  490. ua.accept();
  491. }
  492. public void rejectcall() {
  493. ua.printLog("UA: HANGUP");
  494. ua.hangup();
  495. }
  496. public void togglehold() {
  497. ua.reInvite(null, 0);
  498. }
  499. public void transfer(String number) {
  500. ua.callTransfer(number, 0);
  501. }
  502. public void togglemute() {
  503. if (ua.muteMediaApplication())
  504. Receiver.onText(Receiver.CALL_NOTIFICATION, getUIContext().getString(R.string.menu_mute), android.R.drawable.stat_notify_call_mute,Receiver.ccCall.base);
  505. else
  506. Receiver.progress();
  507. }
  508. public void togglebluetooth() {
  509. ua.bluetoothMediaApplication();
  510. Receiver.progress();
  511. }
  512. public int speaker(int mode) {
  513. int ret = ua.speakerMediaApplication(mode);
  514. Receiver.progress();
  515. return ret;
  516. }
  517. public void keepAlive() {
  518. int i = 0;
  519. for (KeepAliveSip ka : kas) {
  520. if (ka != null && Receiver.on_wlan && isRegistered(i))
  521. try {
  522. ka.sendToken();
  523. Receiver.alarm(60, LoopAlarm.class);
  524. } catch (IOException e) {
  525. if (!Sipdroid.release) e.printStackTrace();
  526. }
  527. i++;
  528. }
  529. }
  530. }