umtsmon is a tool to handle UMTS (3G) devices in Linux This is a port to TDE from https://sourceforge.net/p/umtsmon/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

558 lines
16KB

  1. /* umtsmon - a program to control/monitor your UMTS card
  2. * Copyright (C) 2006, 2007, 2008, 2009 Klaas van Gend, Christofer Wesseling
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation
  7. * applicable version is GPL version 2 only.
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program; if not, write to the Free Software
  14. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. /****************************************************************************
  17. ** ui.h extension file, included from the uic-generated form implementation.
  18. **
  19. ** If you want to add, delete, or rename functions or slots, use
  20. ** TQt Designer to update this file, preserving your code.
  21. **
  22. ** You should not define a constructor or destructor in this file.
  23. ** Instead, write your code in functions called init() and destroy().
  24. ** These will automatically be called by the form's constructor and
  25. ** destructor.
  26. *****************************************************************************/
  27. #include "umtsmon_global.h"
  28. #include "TheDeviceManagerSingleton.h"
  29. #include "PPPConnection.h"
  30. #include "Popup.h"
  31. #include "UIState.h"
  32. #include "ntqlabel.h"
  33. #include "ntqlineedit.h"
  34. #include "ntqtextedit.h"
  35. #include <assert.h>
  36. #include <sys/types.h>
  37. #include <sys/stat.h>
  38. #include <unistd.h>
  39. // it's actually defined in main.cpp
  40. extern const char* theGeneralAutoConnectSettingName;
  41. void mainwindow::init()
  42. {
  43. theConnectionPtr = new DummyConnection();
  44. setCaption("UMTSmon");
  45. menu_help_about->setMenuText( tr("&About %1").arg(APPNAME) );
  46. menu_connection_exit->setMenuText(tr("&Quit %1").arg(APPNAME) );
  47. Toolbar->setCaption(APPNAME" Toolbar");
  48. // FIXME: for now, this will automatically handle the SIMHandler.askforPIN().
  49. theUIStatePtr = new UIState(this);
  50. theConnectionPtr->attach(theUIStatePtr);
  51. // the autoconnect item is a toggle one
  52. menu_settings_AutoConnect->setToggleAction(true);
  53. menu_settings_AutoConnect->setOn(TheSettingsSingleton::getTQSRef().readBoolEntry(theGeneralAutoConnectSettingName, false));
  54. }
  55. void mainwindow::showAboutDialog()
  56. {
  57. DEBUG5("About dialog clicked\n");
  58. AboutDialogUmtsmon myDialog;
  59. myDialog.versionlabel->setText("<b>"APPNAME"</b> version <b>"APPRELEASE "" APPFLAVOUR "</b>");
  60. // no AT commands in this dialog - no exec() prevention needed
  61. myDialog.exec();
  62. }
  63. void mainwindow::showInfoDialog()
  64. {
  65. DEBUG5("info dialog clicked\n");
  66. if (theUIStatePtr->getState() > UIState::REGISTERED)
  67. {
  68. Popup::Info(tr("Sorry, the Info dialog cannot be shown\nwhilst a PPP connection exists."), this);
  69. return;
  70. }
  71. if (theUIStatePtr->getState() < UIState::REGISTERING)
  72. {
  73. Popup::Info(tr("Sorry, the Info dialog cannot be shown right now."), this);
  74. return;
  75. }
  76. InfoDialogUmtsmon myDialog;
  77. myDialog.lbl_pppd_version->setText(theConnectionPtr->getPPPVersion());
  78. myDialog.exec();
  79. }
  80. void mainwindow::setPINmenu(PINState myPINState)
  81. {
  82. bool isOn = (myPINState == PIN_ENABLED);
  83. bool isEnabled = (myPINState == PIN_DISABLED);
  84. menu_pin_enable->setOn(isOn);
  85. menu_pin_enable->setEnabled(isEnabled);
  86. menu_pin_disable->setOn(isEnabled);
  87. menu_pin_disable->setEnabled(isOn);
  88. menu_pin_change->setEnabled(isOn);
  89. }
  90. void mainwindow::DisablePINProtection()
  91. {
  92. SIMHandler mySIMHandler;
  93. EnterPIN myPIN;
  94. myPIN.enableValidator();
  95. myPIN.setSIMHandlerPtr(&mySIMHandler);
  96. myPIN.exec(); // shows the dialog, blocking all other..
  97. if(myPIN.result() == TQDialog::Rejected)
  98. return;
  99. if(!mySIMHandler.setPINActive(false,myPIN.pinField->text(),this))
  100. Popup::Warning(tr("Disabling PIN protection failed.\n"
  101. "Try again, and be sure to use the correct current PIN!"), this);
  102. else
  103. {
  104. //switch the toggle state....
  105. setPINmenu(PIN_DISABLED);
  106. Popup::Info(tr("Disabling PIN protection was successful."), this);
  107. }
  108. }
  109. void mainwindow::EnablePINProtection()
  110. {
  111. SIMHandler mySIMHandler;
  112. EnterPIN myPIN;
  113. myPIN.enableValidator();
  114. myPIN.setSIMHandlerPtr(&mySIMHandler);
  115. myPIN.exec(); // shows the dialog, blocking all other..
  116. if(myPIN.result() == TQDialog::Rejected)
  117. return;
  118. if(!mySIMHandler.setPINActive(true,myPIN.pinField->text(),this))
  119. Popup::Warning(tr("Enabling PIN protection failed.\n"
  120. "Try again, and be sure to use the correct current PIN!"), this);
  121. else
  122. {
  123. setPINmenu(PIN_ENABLED);
  124. Popup::Info(tr("Enabling PIN protection was successful."), this);
  125. }
  126. }
  127. void mainwindow::ChangePIN()
  128. {
  129. DEBUG5("change PIN settings clicked\n");
  130. SIMHandler mySIMHandler;
  131. EnterPIN myCurrentPIN;
  132. myCurrentPIN.enableValidator();
  133. myCurrentPIN.setSIMHandlerPtr(&mySIMHandler);
  134. myCurrentPIN.errorMessage->setText(tr("Please enter your current PIN."));
  135. myCurrentPIN.exec(); // shows the dialog, blocking all other..
  136. if(myCurrentPIN.result() == TQDialog::Rejected) return;
  137. EnterPIN myNewPIN;
  138. myNewPIN.enableValidator();
  139. myNewPIN.setSIMHandlerPtr(&mySIMHandler);
  140. myNewPIN.errorMessage->setText(tr("Please enter your NEW pin."));
  141. myNewPIN.exec(); // shows the dialog, blocking all other..
  142. if(myNewPIN.result() == TQDialog::Rejected) return;
  143. EnterPIN myNewPINsec;
  144. myNewPINsec.enableValidator();
  145. myNewPINsec.setSIMHandlerPtr(&mySIMHandler);
  146. myNewPINsec.errorMessage->setText(tr("Please enter your NEW pin again."));
  147. myNewPINsec.exec(); // shows the dialog, blocking all other..
  148. if(myNewPINsec.result() == TQDialog::Rejected) return;
  149. if(!myNewPINsec.pinField->text().contains(myNewPIN.pinField->text() ) )
  150. {
  151. Popup::Warning(tr("Changing PIN failed.\n"
  152. "New PIN and verify PIN were not same, please try again!"), this);
  153. }
  154. else if(! mySIMHandler.setNewPIN(myCurrentPIN.pinField->text(),myNewPIN.pinField->text(),this))
  155. {
  156. Popup::Warning(tr("Changing PIN failed.\n"
  157. "Try again, and be sure to use the correct current PIN!"), this);
  158. }
  159. else
  160. {
  161. Popup::Info(tr("PIN changed successfully."), this);
  162. }
  163. }
  164. void mainwindow::PushButtonCreateSMS_clicked()
  165. {
  166. DEBUG5("mainwindow::PushButtonCreateSMS_clicked()\n");
  167. if (checkRegistered()==true)
  168. {
  169. Popup::WarningWithMemory("SMSMayFailMsg", tr("The text message (SMS) part"
  170. " of umtsmon is not very stable. It may not work at all.\n"
  171. "Please set your expectations accordingly..."), this);
  172. smsdialog myDialog;
  173. ifATPortAvailableRunExec(&myDialog);
  174. }
  175. else
  176. {
  177. Popup::Warning(tr("You are not connected to a network yet.\n"
  178. "SMS functions are unavailable."), this);
  179. }
  180. }
  181. void mainwindow::showPPPErrorLogsDialog()
  182. {
  183. PPPErrorLogsDialog myPPPDialog;
  184. TQStringList::Iterator it;
  185. if (theConnectionPtr->thePPPDStdOut.count() > 0)
  186. {
  187. for (it = theConnectionPtr->thePPPDStdOut.begin();
  188. it != theConnectionPtr->thePPPDStdOut.end(); ++it )
  189. {
  190. myPPPDialog.StdOutTextBox->append(*it);
  191. }
  192. }
  193. else
  194. myPPPDialog.StdOutTextBox->append(
  195. tr("<<PPP did not provide any stdout information>>"));
  196. if (theConnectionPtr->thePPPDStdErr.count() > 0)
  197. {
  198. for (it = theConnectionPtr->thePPPDStdErr.begin();
  199. it != theConnectionPtr->thePPPDStdErr.end(); ++it )
  200. {
  201. myPPPDialog.StdErrTextBox->append(*it);
  202. }
  203. }
  204. else
  205. myPPPDialog.StdErrTextBox->append(
  206. tr("<<PPP did not provide any stderr information>>"));
  207. myPPPDialog.exec();
  208. }
  209. void mainwindow::updateNetworkData()
  210. {
  211. DEBUG5("mainwindow::updateNetworkData()\n");
  212. const int mySecondsSinceRefresh=UIState::SEC_REFRESH;
  213. ConnectionInfo* myCIPtr = TheDeviceManagerSingleton::getConnectionInfoPtr();
  214. if (myCIPtr == NULL)
  215. return;
  216. // there's three situations here:
  217. // 1) minimized - display in title bar
  218. // 2) maximized, in network tab - update fields inside that tab
  219. // 3) maximized, not in network - do nothing
  220. theConnectionPtr->isConnectionActive();
  221. try { myCIPtr->refresh(); }
  222. catch (MonthRolloverException)
  223. {
  224. Popup::Warning(tr("Your computer just ran into a new month.\n"
  225. "Due to limitations of pppd, we cannot account new "
  226. "traffic to the new month. Please close the connection "
  227. "and reconnect at your earliest convenience."));
  228. }
  229. catch (OverThresholdException e)
  230. {
  231. if (e.getThreshReached()==OverThresholdException::TRAFFIC)
  232. Popup::Warning(tr("You are over your data limit treshold."));
  233. else
  234. Popup::Warning(tr("You are over your time limit treshold."));
  235. }
  236. // and update title bar or fields with data
  237. if (isMinimized())
  238. {
  239. DEBUG5("umtsmon minimized - change titlebar\n");
  240. TQString myRT = myCIPtr->getRadiotype();
  241. TQString myTotalName = APPNAME " " + myRT + " " + myCIPtr->getSignalQualityString();
  242. setCaption( myTotalName );
  243. }
  244. else
  245. {
  246. setCaption(APPNAME);
  247. // only the last one needs to have the LCDDisplay redraw
  248. theLCDDisplay->setStrength(myCIPtr->getSignalQuality(), false);
  249. theLCDDisplay->setRoaming( myCIPtr->isRoaming());
  250. theLCDDisplay->setOperatorName( myCIPtr->getOperatorName(), false);
  251. theLCDDisplay->setRadioType( myCIPtr->getRadiotype(), false );
  252. theLCDDisplay->setUpload(myCIPtr->getCounterBytesSent(),
  253. myCIPtr->getUploadDelta() / mySecondsSinceRefresh, false);
  254. theLCDDisplay->setDownload(myCIPtr->getCounterBytesReceived(),
  255. myCIPtr->getDownloadDelta() / mySecondsSinceRefresh, false);
  256. theLCDDisplay->setConnectedTime(myCIPtr->getSecondsConnected(), false);
  257. // alternate in the display between the total time and total bytes
  258. static int theVisualCounter = 0;
  259. theVisualCounter++;
  260. if (theVisualCounter < 3)
  261. theLCDDisplay->setTotalTraffic(
  262. myCIPtr->getTotalTraffic(),
  263. myCIPtr->getTrafficThresholdStatus(), true);
  264. else
  265. {
  266. theLCDDisplay->setTotalTime(
  267. myCIPtr->getTotalSecondsConnected(),
  268. myCIPtr->getTimeThresholdStatus(), true);
  269. if (theVisualCounter >4)
  270. theVisualCounter = 0;
  271. }
  272. }
  273. }
  274. // no need to pass any state info - we can get that from
  275. // the UIState class :-D
  276. void mainwindow::setConnectButtons(void)
  277. {
  278. bool isConnectEnabled = false;
  279. bool isConnectOn = false;
  280. bool isDisconnectEnabled = false;
  281. switch(theUIStatePtr->getState())
  282. {
  283. case UIState::NO_DEVICE:
  284. case UIState::DETECTING_DEVICE:
  285. case UIState::DEVICE_UNUSABLE:
  286. case UIState::SIM_CHECK:
  287. case UIState::REGISTERING:
  288. case UIState::PPPDISCONNECTING:
  289. // these seven states all have none of the buttons enabled
  290. break;
  291. case UIState::REGISTERED:
  292. isConnectEnabled = true;
  293. break;
  294. case UIState::PPPCONNECTED:
  295. isDisconnectEnabled = true;
  296. // deliberately no break here
  297. case UIState::PPPCONNECTING:
  298. isConnectOn = true;
  299. break;
  300. }
  301. // and set all UI items in the right state:
  302. menu_connection_connect->setOn( isConnectOn );
  303. menu_connection_connect->setEnabled( isConnectEnabled );
  304. menu_connection_disconnect->setOn( !isConnectOn );
  305. menu_connection_disconnect->setEnabled( isDisconnectEnabled );
  306. toolbar_button_connect->setEnabled( isConnectEnabled );
  307. toolbar_button_disconnect->setEnabled( isDisconnectEnabled );
  308. }
  309. bool mainwindow::DisconnectPPP()
  310. {
  311. DEBUG4("umtsmonmain::DisconnectPPP\n");
  312. theUIStatePtr->setState(UIState::PPPDISCONNECTING);
  313. theConnectionPtr->stopConnection();
  314. return true;
  315. }
  316. bool mainwindow::checkRegistered(bool isShowPopups)
  317. {
  318. if (theUIStatePtr->getState()==UIState::REGISTERED)
  319. return true;
  320. if (theUIStatePtr->getState()==UIState::REGISTERING && isShowPopups)
  321. Popup::Info("There is no connection with a mobile network yet.\n"
  322. "Please wait a few more seconds. If the problem remains,"
  323. "try selecting another network operator.");
  324. return false;
  325. }
  326. bool mainwindow::ConnectPPP()
  327. {
  328. DEBUG3("umtsmonmain::ConnectPPP\n");
  329. // check if we are registered on a network already
  330. if (checkRegistered()==false)
  331. return false;
  332. // we are - let's start the PPP!
  333. // startConnection doesn't block for more than 6 seconds
  334. // - so we can do relatively adequate progress reports
  335. ProgressDialog myProgress(this, tr("Setting up Internet Connection"));
  336. myProgress.setMaxTime(30);
  337. // connection will take time anyway, so better show progress from start
  338. myProgress.start(0);
  339. // FIXME: all the tricks are still here in the UI code :-(
  340. theUIStatePtr->setState(UIState::PPPCONNECTING);
  341. if(theConnectionPtr->startConnection()==false)
  342. goto problems;
  343. DEBUG2("thePPPConnection.startConnection() returned without indicating problems\n");
  344. while (theConnectionPtr->isConnectionStarting())
  345. {
  346. if (myProgress.runOneSecond() == false)
  347. {
  348. // Apparently, the user pressed cancel?!
  349. goto cleanup;
  350. }
  351. }
  352. myProgress.finish();
  353. if (theConnectionPtr->hasErrors())
  354. goto problems;
  355. emit theUIStatePtr->update();
  356. return true;
  357. //---------------------
  358. problems:
  359. DEBUG1("start PPP NOT successful :-(\n");
  360. // FIXME: Do we still need this warning message?
  361. Popup::Warning(tr("Failed to start PPP.\n"
  362. "Please re-run umtsmon from the commandline with -v5 and check the output."), this);
  363. cleanup:
  364. sleep(1);
  365. DisconnectPPP();
  366. emit theUIStatePtr->update();
  367. return false;
  368. }
  369. void mainwindow::showProfileDialog()
  370. {
  371. DEBUG5(" profile dialog button clicked\n");
  372. if (theUIStatePtr->getState() <= UIState::REGISTERED)
  373. {
  374. ManageProfiles myDialog;
  375. myDialog.exec();
  376. }
  377. else
  378. {
  379. // FIXME: it's better to adjust the button state
  380. Popup::Warning(tr("Please do not change\nthe profile whilst connected."), this);
  381. }
  382. }
  383. void mainwindow::showNetworkOperatorDialog()
  384. {
  385. DEBUG5(" network operator button clicked\n");
  386. // Only allow switching of operator if no connection active
  387. if (theUIStatePtr->getState() <= UIState::REGISTERED)
  388. {
  389. NetworkOperatorWizard myDialog;
  390. myDialog.exec();
  391. if(myDialog.result() == TQDialog::Accepted)
  392. emit theUIStatePtr->update();
  393. }
  394. }
  395. /** executes the dialog (i.e. aDialogToExecPtr->exec())
  396. * if either of these conditions is met:
  397. * a) the card has more than one serial port
  398. * b) there is no running PPP session.
  399. * Otherwise it will throw a warning dialog.
  400. * @param aDialogToExecPtr TQDialog subclass to run exec() on
  401. * @returns true if dialog was executed, false if not
  402. */
  403. bool mainwindow::ifATPortAvailableRunExec( TQDialog* aDialogToExecPtr)
  404. {
  405. DEBUG5("mainwindow::ifATPortAvailableRunExec()\n");
  406. // test for condition A)
  407. if (TheDeviceManagerSingleton::getDeviceCapsRef().isSinglePort()==false)
  408. {
  409. if (aDialogToExecPtr!=NULL)
  410. aDialogToExecPtr->exec();
  411. return true;
  412. }
  413. // test for condition B)
  414. DEBUG5("only one port available - check if PPP is running?\n");
  415. return ifPPPInactiveRunExec(aDialogToExecPtr);
  416. }
  417. /** executes the dialog (i.e. aDialogToExecPtr->exec())
  418. * IF AND ONLY IF there is no running PPP session.
  419. * Otherwise it will throw a warning dialog.
  420. * @param aDialogToExecPtr TQDialog subclass to run exec() on
  421. * @returns true if dialog was executed, false if not
  422. */
  423. bool mainwindow::ifPPPInactiveRunExec(TQDialog* aDialogToExecPtr)
  424. {
  425. DEBUG5("mainwindow::ifPPPInactiveRunExec()\n");
  426. if (theUIStatePtr->getState()==UIState::REGISTERED)
  427. {
  428. ConnectionInfoInhibitor myParallelATPreventer;
  429. if (aDialogToExecPtr!=NULL)
  430. aDialogToExecPtr->exec();
  431. return true;
  432. }
  433. Popup::Warning(tr("PPP is active, cannot run this in parallel."), this);
  434. return false;
  435. }
  436. void mainwindow::showRadioPreferences()
  437. {
  438. DEBUG1(" showRadioPreferences dialog requested\n");
  439. // this window is modeless - one can keep it open
  440. RadioPreferences myDialog;
  441. myDialog.exec();
  442. myDialog.disconnect();
  443. }
  444. void mainwindow::menu_settings_SetLanguage_activated()
  445. {
  446. SetLanguageDialog myDialog;
  447. myDialog.setI18nPtr(myI18n);
  448. myDialog.exec();
  449. }
  450. void mainwindow::setI18nRef( Internationalisation& anI18nRef )
  451. {
  452. myI18n = &anI18nRef;
  453. }
  454. void mainwindow::menu_settings_AutoConnect_activated()
  455. {
  456. Profile myProfile;
  457. if (myProfile.getWasConnectionSuccess())
  458. TheSettingsSingleton::getTQSRef().writeEntry(theGeneralAutoConnectSettingName,
  459. menu_settings_AutoConnect->isOn());
  460. else
  461. Popup::Info(tr("You can only enable autoconnect"
  462. " once you have made a successful connection."), this);
  463. }
  464. void mainwindow::setNewConnectionBasePtr(void)
  465. {
  466. // this function is called by UIState
  467. // if so - we'd better update the Connection pointer
  468. ConnectionBaseClass* newPtr;
  469. if (TheDeviceManagerSingleton::getDeviceCapsRef().getDeviceType()
  470. == DeviceCapabilities::OPTION_HSO)
  471. newPtr = new HSOConnection(*theConnectionPtr);
  472. else
  473. newPtr = new PPPConnection(*theConnectionPtr);
  474. delete theConnectionPtr;
  475. theConnectionPtr = newPtr;
  476. }