00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "at_engine.h"
00021
00022 #include <qregexp.h>
00023
00024 #include <Q3ValueList>
00025
00026 #include <qtimer.h>
00027 #include <klocale.h>
00028 #include <QWizardPage>
00029 #include <QLabel>
00030 #include <ksharedconfig.h>
00031 #include "wizard/at_connectionspage.h"
00032 #include "wizard/at_devicesfoundpage.h"
00033 #include "wizard/at_scanprogresspage.h"
00034 #include "cfgwidgets/engineconfig.h"
00035
00036 #include <libkmobiletools/picksmscenter.h>
00037 #include <libkmobiletools/smslist.h>
00038 #include <libkmobiletools/weaver.h>
00039 #include <libkmobiletools/enginedata.h>
00040
00041
00042 #include <libkmobiletools/errorhandler.h>
00043
00044
00045 #include "at_jobs.h"
00046 #include "sms_jobs.h"
00047 #include "phonebook_jobs.h"
00048 #include "testphonedevice.h"
00049
00050 #include <config-kmobiletools.h>
00051
00052
00053 using namespace KMobileTools;
00054
00055 AT_Engine::AT_Engine(QObject *parent, const QString &name)
00056 : KMobileTools::Engine(parent, name), p_lastJob(NULL)
00057 {
00058 KGlobal::locale()->insertCatalog( "kmobiletools_at_engine" );
00059 KLocale::setMainCatalog("kmobiletools_at_engine");
00060 device=NULL;
00061
00062 queue_sms=false;
00063 connect( this->engineData(), SIGNAL(connected()), this, SLOT(slotFetchInfos()) );
00064 }
00065
00066
00067 AT_Engine::~AT_Engine()
00068 {
00069 kDebug() <<"AT_Engine::~AT_Engine()";
00070
00071
00072
00073
00074 }
00075 void AT_Engine::queryClose()
00076 {
00077 closeDevice();
00078 KMobileTools::Engine::queryClose();
00079 }
00080
00081
00082 K_PLUGIN_FACTORY( AT_EngineFactory, registerPlugin<AT_Engine>(); )
00083 K_EXPORT_PLUGIN( AT_EngineFactory("kmobiletools_at") )
00084
00085
00086
00089 void AT_Engine::slotSearchPhone()
00090 {
00091 kDebug() <<"********** engine instance name:" << objectName();
00092 searchPhones(static_cast<ATDevicesConfig::Connection>(config()->at_connections()), QStringList(), config()->at_userdevices() );
00093
00095 }
00096
00097
00098 void AT_Engine::slotInitPhone()
00099 {
00111 device=new KMobileTools::SerialManager(this, this->objectName(), engineData()->property("devicePath").toString(), initStrings() );
00112 connect(device, SIGNAL(disconnected()), this, SLOT(connectionStateChanged()));
00113 connect(device, SIGNAL(error()), SIGNAL(error() ) );
00114 p_lastJob=new initPhoneJob(device, this);
00115 enqueueJob( p_lastJob );
00116 }
00117
00118 QStringList AT_Engine::initStrings()
00119 {
00120 QStringList retval( config()->at_initString() );
00121 retval+=config()->at_initString2();
00122 return retval;
00123 }
00124
00125
00126
00127 void AT_Engine::processSlot(KMobileTools::Job* job)
00128 {
00129 KMobileTools::Engine::processSlot(job);
00130
00131 if(job->property("owner") != objectName() ) return;
00132
00133 p_lastJob=0;
00134
00135 KMobileTools::DevicesConfig *wconfig=KMobileTools::DevicesConfig::prefs(objectName() );
00136 switch( job->type() ){
00137 case KMobileTools::Job::initPhone:
00138 kDebug() <<"Device is connected:" << device->isConnected();
00139 engineData()->setPhoneConnected( device->isConnected() );
00140 break;
00141 case KMobileTools::Job::pollStatus:
00142 engineData()->setSignalStrength( ((PollStatus*) job)->phoneSignal() );
00143 engineData()->setCharge( ((PollStatus*) job)->phoneCharge() );
00144 engineData()->setChargeType( ((PollStatus*) job)->phoneChargeType() );
00145 engineData()->setPhoneRinging( ((PollStatus*) job)->ringing() );
00146 break;
00147 case KMobileTools::Job::fetchPhoneInfos:
00148 engineData()->setManufacturer( ( (FetchPhoneInfos*) job )->rawManufacturer() );
00149 engineData()->setModel( ( (FetchPhoneInfos*) job )->model() );
00150 engineData()->setRevision (( (FetchPhoneInfos*) job )->revision() );
00151 engineData()->setIMEI( ( (FetchPhoneInfos*) job )->imei() );
00152 engineData()->setSMSCenter(( (FetchPhoneInfos*) job )->smsCenter() );
00153 if(! engineData()->smsCenter().isNull() )
00154 engineData()->setNetworkName( i18n("Network: %1",
00155 PickSMSCenter::smsCenterName (engineData()->smsCenter() ) ) );
00156 if ( engineData()->manufacturer().contains( "Siemens", Qt::CaseInsensitive ) ) engineData()->setManufacturerID( Siemens);
00157 if ( engineData()->manufacturer().contains( "Motorola", Qt::CaseInsensitive ) ) engineData()->setManufacturerID ( Motorola);
00158 if ( engineData()->manufacturer().contains( "Ericsson", Qt::CaseInsensitive ) ) engineData()->setManufacturerID ( SonyEricsson);
00160
00161
00162 wconfig->writeConfig();
00163 break;
00164 case KMobileTools::Job::fetchAddressBook:
00165 suspendStatusJobs(false);
00166 engineData()->setContactsList( (ContactsList*) &((FetchAddressee*) job )->fullAddresseeList() );
00167
00168
00169
00170
00171 break;
00172 case KMobileTools::Job::fetchSMS:
00173 if( ((FetchSMS*) job)->last()) {
00174 engineData()->setSMSList( ((FetchSMS*)job)->smsList );
00175 queue_sms=false;
00176 }
00177
00178 break;
00179 case KMobileTools::Job::testPhoneFeatures:
00181
00182 wconfig->writeConfig();
00183 break;
00184 case KMobileTools::Job::addAddressee:
00185 slotFetchPhonebook();
00186 if( ((EditAddressees*)job)->pbIsFull() ) {
00188 ErrorHandler::instance()->addError( new BaseError(ERROR_META_INFO) );
00189 }
00190 suspendStatusJobs(false);
00191 break;
00192 case KMobileTools::Job::editAddressee:
00193 slotFetchPhonebook();
00194 if( ((EditAddressees*)job)->pbIsFull() ) {
00196 ErrorHandler::instance()->addError( new BaseError(ERROR_META_INFO) );
00197 }
00198 suspendStatusJobs(false);
00199 break;
00200 case KMobileTools::Job::delAddressee:
00201 slotFetchPhonebook();
00202 suspendStatusJobs(false);
00203 break;
00204 case KMobileTools::Job::selectSMSSlot:
00205 if( ((SelectSMSSlot*) job)->done() )
00206 setSMSSlot( config()->at_smsslots().indexOf( ((SelectSMSSlot*) job)->getReadSlot() ) );
00207 break;
00208 case KMobileTools::Job::delSMS:
00209 if( ! ((DeleteSMS*)job)->succeeded() ) break;
00210
00211 break;
00212 case KMobileTools::Job::storeSMS:
00213 case KMobileTools::Job::sendStoredSMS:
00214 case KMobileTools::Job::sendSMS:
00215 suspendStatusJobs(false);
00216 break;
00217 case KMobileTools::Job::fetchKCal:
00218 #ifdef HAVE_KCAL
00219 suspendStatusJobs(false);
00220 engineData()->setCalendar( p_calendar );
00221 p_calendar->dump();
00222 #endif
00223 break;
00224 case TestPhoneDevice:
00225 l_testphonejobs.removeAll((TestPhoneDeviceJob*)job);
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 kDebug() <<"jobs remaining:" << l_testphonejobs.count();
00238 break;
00239 case FindDeviceData:
00240 emit foundDeviceData((FindDeviceDataJob*) job);
00241 break;
00242 }
00243 }
00244
00245 #include "at_engine.moc"
00246
00247 void AT_Engine::slotPollStatus()
00248 {
00249 if (statusJobsSuspended() ) return;
00250 if(!device) return;
00251 p_lastJob=( new PollStatus(p_lastJob, device, this ) );
00252 enqueueJob(p_lastJob);
00253 }
00254
00255 void AT_Engine::slotFetchInfos()
00256 {
00257 if(!device) return;
00258 enqueueJob ( new FetchPhoneInfos(device, this ) );
00259 enqueueJob ( new TestPhoneFeatures(device, this ) );
00261
00262
00263
00264
00265
00266
00267
00268 p_lastJob=new SelectCharacterSet( p_lastJob, config()->at_encoding(), device, this );
00269 enqueueJob( p_lastJob );
00270 p_lastJob=new SelectSMSSlot( p_lastJob, "ME", device, this );
00271 enqueueJob( p_lastJob );
00272
00273
00274 }
00275
00276 bool AT_Engine::pdu()
00277 {
00278 return atAbilities.isPDU();
00279 }
00280
00281
00285 void AT_Engine::slotFetchPhonebook()
00286 {
00287 if(!device) return;
00288 KMobileTools::Job *job;
00289 if( atAbilities.canSiemensVCF() || atAbilities.canSDBR() )
00290 job=( new FetchAddresseeSiemens(p_lastJob, device, this ) );
00291 else job= ( new FetchAddressee(p_lastJob, availPbSlots(), device, this ) );
00292
00293 p_lastJob=job;
00294 enqueueJob(job);
00295 }
00296
00297 void AT_Engine::setATAbilities( ATAbilities atAbilities )
00298 {
00299 this->atAbilities = atAbilities;
00300 }
00301
00302 ATAbilities AT_Engine::getATAbilities() const
00303 {
00304 return atAbilities;
00305 }
00306
00307
00308 void AT_Engine::slotFetchSMS()
00309 {
00310 if(statusJobsSuspended() || ! device ) return;
00311
00312 if(queue_sms) return;
00313 QStringList sl_slots=config()->at_smsslots();
00314 if( ! sl_slots.count() ) {
00315 kDebug() <<"**** WARNING - this phone is NOT reporting having SMS slots. Perhaps it can't provide SMS. I'm trying anyway to fetch them.";
00316 p_lastJob=new FetchSMS(p_lastJob, SMS::All, device, true, this );
00317 enqueueJob(p_lastJob);
00318 queue_sms=true;
00319 return;
00320 }
00321 for (QStringList::iterator it=sl_slots.begin(); it!=sl_slots.end(); ++it)
00322 {
00323 p_lastJob=new SelectSMSSlot( p_lastJob, (*it), device, this );
00324 enqueueJob( p_lastJob );
00325 p_lastJob=new FetchSMS( p_lastJob, SMS::All, device, *it==sl_slots.last() ,this );
00326 enqueueJob( p_lastJob );
00327 queue_sms=true;
00328 }
00329 }
00330
00334 void AT_Engine::slotAddAddressee(const KABC::Addressee::List& abclist)
00335 {
00336 EditAddressees *tempjob=new EditAddressees(p_lastJob, abclist, device, false, this );
00337 p_lastJob=tempjob;
00338 if(device) enqueueJob( tempjob ) ;
00339 }
00343 void AT_Engine::slotDelAddressee(const KABC::Addressee::List& abclist)
00344 {
00345 if(device) {
00346 p_lastJob=new EditAddressees(p_lastJob, abclist, device, true, this );
00347 enqueueJob(p_lastJob);
00348 }
00349 }
00350
00351 int AT_Engine::availPbSlots()
00352 {
00353 int retval=0;
00354 if ( atAbilities.getPBSlots().indexOf("ME") >=0 ) retval+= PB_Phone;
00355 if ( atAbilities.getPBSlots().indexOf("SM") >=0 ) retval+= PB_SIM;
00356 if ( atAbilities.getPBSlots().indexOf("TA") >=0 ) retval+= PB_DataCard;
00357 return retval;
00358 }
00359
00360
00364 QString AT_Engine::getPBMemSlotString(int memslot)
00365 {
00366 switch( memslot ){
00367 case PB_SIM:
00368 return QString("\"SM\"");
00369 case PB_Phone:
00370 return QString("\"ME\"");
00371 case PB_DataCard:
00372 return QString("\"TA\"");
00373 default:
00374 return QString() ;
00375 }
00376 }
00377
00378
00379 void AT_Engine::slotEditAddressee(const KABC::Addressee& p_oldAddressee, const KABC::Addressee& p_newAddressee)
00380 {
00381 EditAddressees *tempjob=new EditAddressees( p_lastJob, p_oldAddressee, p_newAddressee, device, this );
00382 p_lastJob=tempjob;
00383 if(device) enqueueJob( tempjob );
00384 }
00385
00386
00387 void AT_Engine::slotWeaverSuspended()
00388 {
00389 KMobileTools::Engine::slotWeaverSuspended();
00391
00392 }
00393
00394
00398 void AT_Engine::slotResumeDevice()
00399 {
00400 KMobileTools::Engine::slotResumeDevice();
00402
00403 initPhoneJob* tempjob=new initPhoneJob(device, this);
00404 enqueueJob( tempjob );
00405 p_lastJob=tempjob;
00406 suspendStatusJobs(false);
00407 }
00408
00409
00413 void AT_Engine::slotStopDevice()
00414 {
00415 if(! statusJobsSuspended() ) suspendStatusJobs(true);
00416 if(ThreadWeaver()->queueLength())
00417 {
00418 QTimer::singleShot( 500, this, SLOT(stopDevice()));
00419 return;
00420 }
00421 KMobileTools::Engine::slotStopDevice();
00422 device->close();
00423 }
00424
00425
00429 void AT_Engine::setDevice ( const QString &deviceName)
00430 {
00431
00432 device->setDevicePath(deviceName );
00433 }
00434
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00511 void AT_Engine::slotDelSMS(SMS* sms)
00512 {
00513 if(!device) return;
00514 p_lastJob=new SelectSMSSlot( p_lastJob, sms->rawSlot(), device, this ) ;
00515 enqueueJob(p_lastJob);
00516 p_lastJob=new DeleteSMS( p_lastJob, sms, device, this) ;
00517 }
00518
00519 void AT_Engine::slotStoreSMS( const QString &number, const QString &text)
00520 {
00521 if(!device) return;
00522 p_lastJob=( new StoreSMS(p_lastJob, number, text, device, this ));
00523 enqueueJob(p_lastJob);
00524 }
00525
00526
00527 void AT_Engine::slotSendSMS( const QString &number, const QString &text)
00528 {
00529 if(!device) return;
00530 p_lastJob=( new SendSMS(p_lastJob, number, text, device, this ));
00531 enqueueJob(p_lastJob);
00532 }
00533
00534
00538 void AT_Engine::slotSendSMS(SMS* sms)
00539 {
00540 if(!device) return;
00541 p_lastJob=( new SendSMS(p_lastJob, sms, device, this ) );
00542 enqueueJob(p_lastJob);
00543 }
00544
00545 void AT_Engine::slotSendStoredSMS(SMS* sms)
00546 {
00547 if(!device) return;
00548 p_lastJob=( new SendStoredSMS(p_lastJob, sms, device, this ) );
00549 enqueueJob(p_lastJob);
00550 }
00551
00552
00556 void AT_Engine::slotStoreSMS(SMS* sms)
00557 {
00558 if(!device) return;
00559 p_lastJob=( new StoreSMS(p_lastJob, sms, device, this ) );
00560 enqueueJob(p_lastJob);
00561 }
00562
00563
00567 void AT_Engine::slotFetchCalendar()
00568 {
00569 #ifdef HAVE_KCAL
00570 if(!device) return;
00571 p_lastJob=( new FetchCalendar(p_lastJob, device, this ) );
00572 enqueueJob(p_lastJob);
00573 #endif
00574 }
00575
00576
00580 void AT_Engine::slotDial(DialActions action, const QString &gnumber)
00581 {
00582 uint dialsystem=config()->at_dialsystem();
00583 QString number=gnumber;
00584 switch( action ){
00585 case DIAL_DIAL:
00586 if(number.isNull()) return;
00587 switch( dialsystem ){
00588 case 0:
00589 if( number.at(0)=='+' )
00590 number=number.right( number.length() -1 ).prepend("AT+CKPD=\"0\",20;+CKPD=\"").append("s\"\r" );
00591 else number=number.prepend( "AT+CKPD=\"" ).append( "s\"\r" );
00592 break;
00593 case 1:
00594 number=number.prepend( "ATD" ).append( ";\r" );
00595 break;
00596 }
00597 device->sendATCommand(0, number, 1500);
00598 break;
00599 case DIAL_HANGUP:
00600 switch( dialsystem ){
00601 case 0:
00602 device->sendATCommand(0, "AT+CKPD=\"e\"\r", 1500 );
00603 break;
00604 case 1:
00605 device->sendATCommand( 0, "ATH" );
00606 device->sendATCommand( 0, "AT+CHUP" );
00607 break;
00608 }
00609 break;
00610 }
00611 }
00612
00613 QString AT_Engine::currentDeviceName() const
00614 {
00615 return device->devicePath();
00616 }
00617
00618
00619 QString AT_Engine::engineLibName() const
00620 {
00621 return QString("kmobiletools_at");
00622 }
00623
00627 void AT_Engine::slotSwitchToFSMode()
00628 {
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641 }
00642
00643 QList<QWizardPage*> AT_Engine::wizardPages(QWidget *parentWidget)
00644 {
00645 QList<QWizardPage*> retval;
00646 retval+=new AT_ConnectionsPage(parentWidget);
00647 retval+=new AT_ScanProgressPage(parentWidget);
00648 retval+=new AT_DevicesFoundPage(parentWidget);
00649 return retval;
00650 }
00651
00652 QList<QWidget*> AT_Engine::configWidgets(QWidget *parentWidget)
00653 {
00654 QList<QWidget*> retval;
00655 QWidget *tempPage;
00656 tempPage=new EngineConfigWidget(parentWidget);
00657 tempPage->setProperty("itemName", i18nc("At Engine Configuration Dialog title", "AT Engine") );
00658 tempPage->setProperty("pixmapName", QString("kmobiletoolsAT") );
00659 tempPage->setProperty("header", i18nc("At Engine Configuration Dialog Header", "AT Engine Configuration Page") );
00660 retval+=tempPage;
00661 return retval;
00662 }
00663
00664
00665 QString AT_Engine::parseWizardSummary(const QString &strtemplate, const QString &deviceName) const
00666 {
00667 QString retstr=strtemplate;
00668 ATDevicesConfig *cfg=(ATDevicesConfig*)DEVCFG(deviceName);
00669 int conn=cfg->at_connections();
00670 QStringList tmpstrlist;
00671 if(conn & ATDevicesConfig::ConnectionUSB) tmpstrlist+=i18nc("USB Connection", "USB");
00672 if(conn & ATDevicesConfig::ConnectionSerial) tmpstrlist+=i18nc("Serial Connection", "Serial Ports");
00673 if(conn & ATDevicesConfig::ConnectionBluetooth) tmpstrlist+=i18nc("Bluetooth Connection", "Bluetooth");
00674 if(conn & ATDevicesConfig::ConnectionIrDA) tmpstrlist+=i18nc("IrDA Connection", "Infrared");
00675 if(conn & ATDevicesConfig::ConnectionUser) tmpstrlist+=i18nc("User-defined Connection", "User defined");
00676 kDebug() <<"conn=" << conn <<"; stringlist:" << tmpstrlist;
00677 QString tempstr=i18ncp("AT Wizard summary - using <connection types>", "Using connection: %2", "Using connections: %2",
00678 tmpstrlist.count(), tmpstrlist.join(", ") );
00679 retstr=retstr.arg(tempstr);
00681
00682 retstr=retstr.arg(tempstr);
00684
00685 retstr=retstr.arg(tempstr);
00686
00687 return retstr;
00688 }
00689
00690 ATDevicesConfig *AT_Engine::config(bool forceNew, const QString &groupName) {
00691 QString gpname;
00692 if(groupName.isEmpty()) gpname=objectName(); else gpname=groupName;
00693 kDebug() <<"ATEngine config : force new=" << forceNew <<"; groupname=" << gpname;
00694 if(forceNew)
00695 return new ATDevicesConfig( gpname, gpname );
00696 return (ATDevicesConfig*) ATDevicesConfig::prefs(gpname );
00697 }
00698
00699 void AT_Engine::enqueueTPJob(TestPhoneDeviceJob* pjob) {
00700 l_testphonejobs+=pjob;
00701 enqueueJob(pjob);
00702 }
00703
00704 void AT_Engine::searchPhones(ATDevicesConfig::Connection connections, const QStringList &bluetoothDevices, const QStringList &customDevices) {
00705 if(!connections) return;
00706 QStringList devices;
00707 TestPhoneDeviceJob *curjob;
00708 if(connections & ATDevicesConfig::ConnectionUSB)
00709 for(uchar i=0; i<10; i++) {
00710 enqueueTPJob( new TestPhoneDeviceJob(QString("/dev/ttyACM%1").arg(i), this) );
00711 enqueueTPJob(new TestPhoneDeviceJob(QString("/dev/ttyUSB%1").arg(i), this) );
00712 }
00713 if(connections & ATDevicesConfig::ConnectionIrDA)
00714 for(uchar i=0; i<10; i++) {
00715 enqueueTPJob(new TestPhoneDeviceJob(QString("/dev/ircomm%1").arg(i), this) );
00716 }
00717 if(connections & ATDevicesConfig::ConnectionSerial)
00718 for(uchar i=0; i<10; i++) {
00719 enqueueTPJob(new TestPhoneDeviceJob(QString("/dev/ttyS%1").arg(i), this) );
00720 }
00721 if(connections & ATDevicesConfig::ConnectionBluetooth)
00722 for(QStringList::ConstIterator it=bluetoothDevices.begin(); it!=bluetoothDevices.end(); ++it)
00723 enqueueTPJob(new TestPhoneDeviceJob(*it, this) );
00724 if(connections & ATDevicesConfig::ConnectionUser)
00725 for(QStringList::ConstIterator it=customDevices.begin(); it!=customDevices.end(); ++it)
00726 enqueueTPJob(new TestPhoneDeviceJob(*it, this) );
00727 }
00728
00729 void AT_Engine::connectionStateChanged() {
00730 engineData()->setPhoneConnected( device->isConnected() );
00731 }
00732