kpilot

kpilotdevicelinkPrivate.h

Go to the documentation of this file.
00001 #ifndef _KPILOT_KPILOTDEVICELINKPRIVATE_H
00002 #define _KPILOT_KPILOTDEVICELINKPRIVATE_H
00003 /*
00004 **
00005 ** Copyright (C) 2007 by Jason 'vanRijn' Kasper <vR@movingparts.net>
00006 **
00007 */
00008 
00009 /*
00010 ** This program is free software; you can redistribute it and/or modify
00011 ** it under the terms of the GNU Lesser General Public License as published by
00012 ** the Free Software Foundation; either version 2.1 of the License, or
00013 ** (at your option) any later version.
00014 **
00015 ** This program is distributed in the hope that it will be useful,
00016 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00018 ** GNU Lesser General Public License for more details.
00019 **
00020 ** You should have received a copy of the GNU Lesser General Public License
00021 ** along with this program in a file called COPYING; if not, write to
00022 ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00023 ** MA 02110-1301, USA.
00024 */
00025 
00026 /*
00027 ** Bug reports and questions can be sent to kde-pim@kde.org
00028 */
00029 
00030 #include <errno.h>
00031 
00032 #include <qstringlist.h>
00033 #include <qthread.h>
00034 
00035 #include "kpilotdevicelink.h"
00036 #include "options.h"
00037 
00038 class QTimer;
00039 class QSocketNotifier;
00040 
00041 // singleton helper class
00042 class DeviceMap
00043 {
00044 public:
00045     static DeviceMap *self()
00046     {
00047         if (!mThis)
00048             mThis = new DeviceMap();
00049         return mThis;
00050     }
00051 
00052     bool canBind(const QString &device)
00053     {
00054         FUNCTIONSETUPL(5);
00055         DEBUGKPILOT << fname << ": device: ["
00056             << device << "]" << endl;
00057 
00058         showList();
00059         return !mBoundDevices.contains(device);
00060     }
00061 
00062     void bindDevice(const QString &device)
00063     {
00064         FUNCTIONSETUPL(5);
00065         DEBUGKPILOT << fname << ": device: ["
00066             << device << "]" << endl;
00067 
00068         mBoundDevices.append(device);
00069         showList();
00070     }
00071 
00072     void unbindDevice(const QString &device)
00073     {
00074         FUNCTIONSETUPL(5);
00075         DEBUGKPILOT << fname << ": device: ["
00076             << device << "]" << endl;
00077 
00078         mBoundDevices.remove(device);
00079         showList();
00080     }
00081 
00082 protected:
00083     DeviceMap()
00084     {
00085         mBoundDevices.clear();
00086     }
00087     ~DeviceMap()
00088     {
00089     }
00090 
00091     QStringList mBoundDevices;
00092     static DeviceMap *mThis;
00093 
00094 private:
00095     void showList() const
00096     {
00097         FUNCTIONSETUPL(5);
00098 
00099         if ( !(mBoundDevices.count() > 0))
00100             return;
00101 
00102         DEBUGKPILOT << fname << ": Bound devices: ["
00103             << ((mBoundDevices.count() > 0) ?
00104                     mBoundDevices.join(CSL1(", ")) : CSL1("<none>"))
00105             << "]" << endl;
00106     }
00107 };
00108 
00109 class Messages
00110 {
00111 public:
00112     Messages(KPilotDeviceLink *parent) :
00113         fDeviceLink(parent)
00114     {
00115         reset();
00116     }
00117 
00118     void reset()
00119     {
00120         messages = 0;
00121         messagesMask = ~messageIsError; // Never block errors
00122     }
00123 
00124     void block(unsigned int m, bool force=false)
00125     {
00126         if (force)
00127         {
00128             // Force blocking this message, even if it's an error msg.
00129             messages |= m;
00130         }
00131         else
00132         {
00133             messages |= (m & messagesMask);
00134         }
00135     }
00136 
00142     enum
00143     {
00144         OpenMessage=1, 
00145         OpenFailMessage=2 
00146     };
00147     int messages;
00148     int messagesMask;
00149     static const int messageIsError = 0;
00150 
00156     bool shouldPrint(int msgid)
00157     {
00158         if (!(messages & msgid))
00159         {
00160             block(msgid);
00161             return true;
00162         }
00163         else
00164         {
00165             return false;
00166         }
00167     }
00168 
00169 protected:
00170     KPilotDeviceLink *fDeviceLink;
00171 };
00172 
00173 class DeviceCommEvent : public QEvent
00174 {
00175 public:
00176     DeviceCommEvent(DeviceCustomEvents type, QString msg = QString::null,
00177             int progress = 0) :
00178         QEvent( (QEvent::Type)type ), fMessage(msg), fProgress(progress),
00179                 fPilotSocket(-1)
00180     {
00181     }
00182     QString message() const
00183     {
00184         return fMessage;
00185     }
00186     int progress()
00187     {
00188         return fProgress;
00189     }
00190 
00191     inline void setCurrentSocket(int i)
00192     {
00193         fPilotSocket = i;
00194     }
00195 
00196     inline int currentSocket()
00197     {
00198         return fPilotSocket;
00199     }
00200 private:
00201     QString fMessage;
00202     int fProgress;
00206     int fPilotSocket;
00207 };
00208 
00214 class DeviceCommThread : public QObject, public QThread
00215 {
00216 friend class KPilotDeviceLink;
00217 
00218 Q_OBJECT
00219 
00220 public:
00221     DeviceCommThread(KPilotDeviceLink *d);
00222     virtual ~DeviceCommThread();
00223 
00224     virtual void run();
00225 
00226     void setDone(bool b)
00227     {
00228         FUNCTIONSETUP;
00229         fDone = b;
00230     }
00231 
00232 protected:
00233 
00234     void close();
00235     
00236     void reset();
00237 
00242     bool open(const QString &device = QString::null);
00243 
00244 protected slots:
00249     void openDevice();
00250 
00255     void acceptDevice();
00256     
00262     void workaroundUSB();
00263 
00264 private:
00265     volatile bool fDone;
00266 
00267     KPilotDeviceLink *fHandle;
00268     inline KPilotDeviceLink *link()
00269     {
00270         if (fHandle)
00271         {
00272             return fHandle;
00273         }
00274         else
00275         {
00276             FUNCTIONSETUP;
00277             WARNINGKPILOT << "Link asked for, but either I'm "
00278                 << "done or I don't have a valid handle.  "
00279                 << "Shutting down comm thread." << endl;
00280             QThread::exit();
00281             return 0;
00282         }
00283     }
00284 
00288     QTimer *fOpenTimer;
00289     QSocketNotifier *fSocketNotifier;
00290     bool fSocketNotifierActive;
00291 
00293     QTimer *fWorkaroundUSBTimer;
00294     
00298     int fPilotSocket;
00299     int fTempSocket;
00300 
00301     inline QString errorMessage(int e)
00302     {
00303         switch (e)
00304         {
00305         case ENOENT:
00306             return i18n(" The port does not exist.");
00307             break;
00308         case ENODEV:
00309             return i18n(" There is no such device.");
00310             break;
00311         case EPERM:
00312             return i18n(" You do not have permission to open the "
00313                 "Pilot device.");
00314             break;
00315         default:
00316             return i18n(" Check Pilot path and permissions.");
00317         }
00318     }
00319     
00324     int fAcceptedCount;
00325 
00326 };
00327 
00328 
00329 #endif
00330