PageRenderTime 42ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/swapnapalaniswamy/batphone
Java | 475 lines | 382 code | 64 blank | 29 comment | 127 complexity | e468a8b2971c4abdea671e6f9ca1f185 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 org.servalproject.R;
  24. import org.servalproject.ServalBatPhoneApplication;
  25. import org.sipdroid.media.Bluetooth;
  26. import org.sipdroid.net.KeepAliveSip;
  27. import org.sipdroid.sipua.ui.LoopAlarm;
  28. import org.sipdroid.sipua.ui.Receiver;
  29. import org.sipdroid.sipua.ui.Settings;
  30. import org.zoolu.net.IpAddress;
  31. import org.zoolu.sip.address.NameAddress;
  32. import org.zoolu.sip.provider.SipProvider;
  33. import org.zoolu.sip.provider.SipStack;
  34. import android.content.Context;
  35. import android.content.SharedPreferences.Editor;
  36. import android.net.wifi.WifiManager;
  37. import android.os.Build;
  38. import android.os.PowerManager;
  39. import android.os.SystemClock;
  40. import android.preference.PreferenceManager;
  41. import android.util.Log;
  42. public class SipdroidEngine implements RegisterAgentListener {
  43. public static final int LINES = 1;
  44. public int pref=0;
  45. public static final int UNINITIALIZED = 0x0;
  46. public static final int INITIALIZED = 0x2;
  47. /** User Agent */
  48. public UserAgent[] uas;
  49. public UserAgent ua;
  50. /** Register Agent */
  51. private RegisterAgent[] ras;
  52. private KeepAliveSip[] kas;
  53. /** UserAgentProfile */
  54. public UserAgentProfile[] user_profiles;
  55. public SipProvider[] sip_providers;
  56. public static PowerManager.WakeLock[] wl,pwl;
  57. public boolean StartEngine() {
  58. PowerManager pm = (PowerManager) getUIContext().getSystemService(Context.POWER_SERVICE);
  59. if (wl == null) {
  60. wl = new PowerManager.WakeLock[LINES];
  61. pwl = new PowerManager.WakeLock[LINES];
  62. }
  63. uas = new UserAgent[LINES];
  64. ras = new RegisterAgent[LINES];
  65. kas = new KeepAliveSip[LINES];
  66. lastmsgs = new String[LINES];
  67. sip_providers = new SipProvider[LINES];
  68. user_profiles = new UserAgentProfile[LINES];
  69. user_profiles[0] = new UserAgentProfile();
  70. SipStack.init(null);
  71. int i = 0;
  72. for (UserAgentProfile user_profile : user_profiles) {
  73. if (user_profile==null) continue;
  74. if (wl[i] == null) {
  75. wl[i] = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Sipdroid.SipdroidEngine");
  76. pwl[i] = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "Sipdroid.SipdroidEngine");
  77. }
  78. try {
  79. SipStack.max_retransmission_timeout = 4000;
  80. SipStack.default_transport_protocols = new String[1];
  81. SipStack.default_transport_protocols[0] = "udp";
  82. String version = "Batphone/" + ServalBatPhoneApplication.version + "/" + Build.MODEL;
  83. SipStack.ua_info = version;
  84. SipStack.server_info = version;
  85. sip_providers[i] = new SipProvider(IpAddress.localIpAddress, 0);
  86. user_profile.contact_url = getContactURL(user_profile.username,sip_providers[i]);
  87. // added by mandrajg
  88. uas[i] = ua = new UserAgent(sip_providers[i], user_profile);
  89. ras[i] = new RegisterAgent(sip_providers[i], user_profile.from_url, // modified
  90. user_profile.contact_url, user_profile.username,
  91. user_profile.realm, user_profile.passwd, this, user_profile,
  92. user_profile.pub); // added by mandrajg
  93. kas[i] = new KeepAliveSip(sip_providers[i],100000);
  94. } catch (Exception E) {
  95. Log.v("SipDroid","Start Engine failure",E);
  96. }
  97. i++;
  98. }
  99. register();
  100. listen();
  101. return true;
  102. }
  103. private String getContactURL(String username,SipProvider sip_provider) {
  104. int i = username.indexOf("@");
  105. if (i != -1) {
  106. // if the username already contains a @
  107. //strip it and everthing following it
  108. username = username.substring(0, i);
  109. }
  110. return username + "@" + IpAddress.localIpAddress
  111. + (sip_provider.getPort() != 0?":"+sip_provider.getPort():"")
  112. + ";transport=" + sip_provider.getDefaultTransport();
  113. }
  114. public Context getUIContext() {
  115. return Receiver.mContext;
  116. }
  117. public int getRemoteVideo() {
  118. return ua.remote_video_port;
  119. }
  120. public int getLocalVideo() {
  121. return ua.local_video_port;
  122. }
  123. public String getRemoteAddr() {
  124. return ua.remote_media_address;
  125. }
  126. public void expire() {
  127. Receiver.expire_time = 0;
  128. int i = 0;
  129. for (RegisterAgent ra : ras) {
  130. if (ra != null && ra.CurrentState == RegisterAgent.REGISTERED) {
  131. ra.CurrentState = RegisterAgent.UNREGISTERED;
  132. }
  133. i++;
  134. }
  135. register();
  136. }
  137. public void unregister(int i) {
  138. if (user_profiles[i] == null || user_profiles[i].username.equals("") ||
  139. user_profiles[i].realm.equals("")) return;
  140. RegisterAgent ra = ras[i];
  141. if (ra != null && ra.unregister()) {
  142. Receiver.alarm(0, LoopAlarm.class);
  143. wl[i].acquire();
  144. }
  145. }
  146. public void registerMore() {
  147. int i = 0;
  148. for (RegisterAgent ra : ras) {
  149. try {
  150. if (user_profiles[i] == null || user_profiles[i].username.equals("") ||
  151. user_profiles[i].realm.equals("")) {
  152. i++;
  153. continue;
  154. }
  155. user_profiles[i].contact_url = getContactURL(user_profiles[i].from_url,sip_providers[i]);
  156. if (ra != null && !ra.isRegistered() && true && ra.register()) {
  157. wl[i].acquire();
  158. }
  159. } catch (Exception ex) {
  160. Log.v("SipDroid","Failed to register",ex);
  161. }
  162. i++;
  163. }
  164. }
  165. public void register() {
  166. int i = 0;
  167. for (RegisterAgent ra : ras) {
  168. try {
  169. if (user_profiles[i] == null || user_profiles[i].username.equals("") ||
  170. user_profiles[i].realm.equals("")) {
  171. i++;
  172. continue;
  173. }
  174. user_profiles[i].contact_url = getContactURL(user_profiles[i].from_url,sip_providers[i]);
  175. if (ra != null && ra.register()) {
  176. wl[i].acquire();
  177. }
  178. } catch (Exception ex) {
  179. Log.v("SipDroid","Failed to register",ex);
  180. }
  181. i++;
  182. }
  183. }
  184. public void registerUdp() {
  185. int i = 0;
  186. for (RegisterAgent ra : ras) {
  187. try {
  188. if (user_profiles[i] == null || user_profiles[i].username.equals("") ||
  189. user_profiles[i].realm.equals("") ||
  190. sip_providers[i] == null ||
  191. sip_providers[i].getDefaultTransport() == null ||
  192. sip_providers[i].getDefaultTransport().equals("tcp")) {
  193. i++;
  194. continue;
  195. }
  196. user_profiles[i].contact_url = getContactURL(user_profiles[i].from_url,sip_providers[i]);
  197. if (ra != null && ra.register()) {
  198. wl[i].acquire();
  199. }
  200. } catch (Exception ex) {
  201. Log.v("SipDroid","Failed to register udp",ex);
  202. }
  203. i++;
  204. }
  205. }
  206. public void halt() { // modified
  207. if (ras==null) return;
  208. long time = SystemClock.elapsedRealtime();
  209. int i = 0;
  210. for (RegisterAgent ra : ras) {
  211. unregister(i);
  212. while (ra != null && ra.CurrentState != RegisterAgent.UNREGISTERED && SystemClock.elapsedRealtime()-time < 2000)
  213. try {
  214. Thread.sleep(100);
  215. } catch (InterruptedException e1) {
  216. }
  217. if (wl[i].isHeld()) {
  218. wl[i].release();
  219. if (pwl[i] != null && pwl[i].isHeld()) pwl[i].release();
  220. }
  221. if (kas[i] != null) {
  222. Receiver.alarm(0, LoopAlarm.class);
  223. kas[i].halt();
  224. }
  225. if (ra != null)
  226. ra.halt();
  227. if (uas[i] != null)
  228. uas[i].hangup();
  229. if (sip_providers[i] != null)
  230. sip_providers[i].halt();
  231. i++;
  232. }
  233. }
  234. static SipdroidEngine engine=null;
  235. public static boolean isRegistered()
  236. {
  237. if (engine==null)
  238. return false;
  239. for (RegisterAgent ra : engine.ras)
  240. if (ra != null && ra.isRegistered())
  241. return true;
  242. return false;
  243. }
  244. public static boolean hasAudio(){
  245. return (engine != null &&
  246. engine.ua != null &&
  247. engine.ua.audio_app != null);
  248. }
  249. public static synchronized SipdroidEngine getEngine() {
  250. if (engine == null) {
  251. engine = new SipdroidEngine();
  252. if (Integer.parseInt(Build.VERSION.SDK) >= 8)
  253. Bluetooth.init();
  254. }
  255. return engine;
  256. }
  257. boolean isRegistered(int i)
  258. {
  259. if (ras[i] == null)
  260. {
  261. return false;
  262. }
  263. return ras[i].isRegistered();
  264. }
  265. public void onUaRegistrationSuccess(RegisterAgent reg_ra, NameAddress target,
  266. NameAddress contact, String result) {
  267. int i = 0;
  268. for (RegisterAgent ra : ras) {
  269. if (ra == reg_ra) break;
  270. i++;
  271. }
  272. if (isRegistered(i)) {
  273. if (Receiver.on_wlan)
  274. Receiver.alarm(60, LoopAlarm.class);
  275. reg_ra.subattempts = 0;
  276. reg_ra.startMWI();
  277. }
  278. if (wl[i].isHeld()) {
  279. wl[i].release();
  280. if (pwl[i] != null && pwl[i].isHeld()) pwl[i].release();
  281. }
  282. }
  283. String[] lastmsgs;
  284. public void onMWIUpdate(RegisterAgent mwi_ra, boolean voicemail, int number, String vmacc) {
  285. int i = 0;
  286. for (RegisterAgent ra : ras) {
  287. if (ra == mwi_ra) break;
  288. i++;
  289. }
  290. if (voicemail) {
  291. String msgs = getUIContext().getString(R.string.voicemail);
  292. if (number != 0) {
  293. msgs = msgs + ": " + number;
  294. }
  295. Receiver.MWI_account = vmacc;
  296. if (lastmsgs[i] == null || !msgs.equals(lastmsgs[i])) {
  297. Receiver.onText(Receiver.MWI_NOTIFICATION, msgs,android.R.drawable.stat_notify_voicemail,0);
  298. lastmsgs[i] = msgs;
  299. }
  300. } else {
  301. Receiver.onText(Receiver.MWI_NOTIFICATION, null, 0,0);
  302. lastmsgs[i] = null;
  303. }
  304. }
  305. static long lasthalt,lastpwl;
  306. /** When a UA failed on (un)registering. */
  307. public void onUaRegistrationFailure(RegisterAgent reg_ra, NameAddress target,
  308. NameAddress contact, String result) {
  309. boolean retry = false;
  310. int i = 0;
  311. for (RegisterAgent ra : ras) {
  312. if (ra == reg_ra) break;
  313. i++;
  314. }
  315. if (isRegistered(i)) {
  316. reg_ra.CurrentState = RegisterAgent.UNREGISTERED;
  317. } else {
  318. retry = true;
  319. }
  320. if (retry && SystemClock.uptimeMillis() > lastpwl + 45000 && pwl[i] != null && !pwl[i].isHeld() && Receiver.on_wlan) {
  321. lastpwl = SystemClock.uptimeMillis();
  322. if (wl[i].isHeld())
  323. wl[i].release();
  324. pwl[i].acquire();
  325. register();
  326. if (!wl[i].isHeld() && pwl[i].isHeld()) pwl[i].release();
  327. } else if (wl[i].isHeld()) {
  328. wl[i].release();
  329. if (pwl[i] != null && pwl[i].isHeld()) pwl[i].release();
  330. }
  331. if (SystemClock.uptimeMillis() > lasthalt + 45000) {
  332. lasthalt = SystemClock.uptimeMillis();
  333. sip_providers[i].haltConnections();
  334. }
  335. reg_ra.stopMWI();
  336. WifiManager wm = (WifiManager) Receiver.mContext.getSystemService(Context.WIFI_SERVICE);
  337. wm.startScan();
  338. }
  339. /** Receives incoming calls (auto accept) */
  340. public void listen()
  341. {
  342. for (UserAgent ua : uas) {
  343. if (ua != null) {
  344. ua.printLog("UAS: WAITING FOR INCOMING CALL");
  345. if (!ua.user_profile.audio && !ua.user_profile.video)
  346. {
  347. ua.printLog("ONLY SIGNALING, NO MEDIA");
  348. }
  349. ua.listen();
  350. }
  351. }
  352. }
  353. public void info(char c, int duration) {
  354. ua.info(c, duration);
  355. }
  356. /** Makes a new call */
  357. public boolean call(String target_url) {
  358. return ua.call(target_url);
  359. }
  360. public void answercall()
  361. {
  362. Receiver.stopRingtone();
  363. ua.accept();
  364. }
  365. public void rejectcall() {
  366. ua.printLog("UA: HANGUP");
  367. ua.hangup();
  368. }
  369. public void togglehold() {
  370. ua.reInvite(null, 0);
  371. }
  372. public void transfer(String number) {
  373. ua.callTransfer(number, 0);
  374. }
  375. public void togglemute() {
  376. if (ua.muteMediaApplication())
  377. Receiver.onText(Receiver.CALL_NOTIFICATION, getUIContext().getString(R.string.menu_mute), android.R.drawable.stat_notify_call_mute,Receiver.ccCall.base);
  378. else
  379. Receiver.progress();
  380. }
  381. public void togglebluetooth() {
  382. ua.bluetoothMediaApplication();
  383. Receiver.progress();
  384. }
  385. public int speaker(int mode) {
  386. int ret = ua.speakerMediaApplication(mode);
  387. Receiver.progress();
  388. return ret;
  389. }
  390. public void keepAlive() {
  391. int i = 0;
  392. for (KeepAliveSip ka : kas) {
  393. if (ka != null && Receiver.on_wlan && isRegistered(i))
  394. try {
  395. ka.sendToken();
  396. Receiver.alarm(60, LoopAlarm.class);
  397. } catch (IOException e) {
  398. Log.v("SipDroid","keep alive failed",e);
  399. }
  400. i++;
  401. }
  402. }
  403. public static boolean on(Context context) {
  404. return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(Settings.PREF_ON, Settings.DEFAULT_ON);
  405. }
  406. public static void on(Context context,boolean on) {
  407. Editor edit = PreferenceManager.getDefaultSharedPreferences(context).edit();
  408. edit.putBoolean(Settings.PREF_ON, on);
  409. edit.commit();
  410. }
  411. }