From a9fe8f28a4a9aaf1d9b84dbc6907849ace87f66e Mon Sep 17 00:00:00 2001 From: Fritz Elfert Date: Tue, 6 Feb 2001 01:01:46 +0000 Subject: - Added KDE2 PropsDialog Plugin (incomplete) - Fixed some KDE related autoconf stuff - Added PlpDrive class for returning results from rfsv:devinfo - Added auto-watch in ppsocket and finally got rid of the nasty SIGPIPE bug. Now it's no more necessary to ignore SIGPIPE in applications. - Made constructors of rfsv16, rfsv32, rpcs16 and rpcs32 private to enforce use of the factories. - Removed error output in the factories and replaced that by error codes which can be retrieved and evaluated by an application. --- lib/Makefile.am | 3 +- lib/plpdirent.cc | 138 ++++++++++++++++++++++++++++++++++++++++++++ lib/plpdirent.h | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/ppsocket.cc | 64 ++++++++++++++------- lib/ppsocket.h | 17 ++++-- lib/rfsv.h | 24 +++++--- lib/rfsv16.cc | 45 +++++++++++---- lib/rfsv16.h | 19 +++++-- lib/rfsv32.cc | 15 ++--- lib/rfsv32.h | 19 +++++-- lib/rfsvfactory.cc | 31 ++++++---- lib/rfsvfactory.h | 22 +++++++ lib/rpcs16.h | 12 +++- lib/rpcs32.h | 53 +++++++++-------- lib/rpcsfactory.cc | 27 +++++++-- lib/rpcsfactory.h | 22 +++++++ 16 files changed, 573 insertions(+), 102 deletions(-) (limited to 'lib') diff --git a/lib/Makefile.am b/lib/Makefile.am index 367fbb7..7e56949 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -2,7 +2,8 @@ # lib_LTLIBRARIES = libplp.la -libplp_la_LDFLAGS = --debug -version-info 1:1:0 +libplp_la_LDFLAGS = $(LIBDEBUG) -version-info $(LIBVERSION) + libplp_la_SOURCES = bufferarray.cc bufferstore.cc iowatch.cc ppsocket.cc \ rfsv16.cc rfsv32.cc rfsvfactory.cc log.cc rfsv.cc rpcs32.cc rpcs16.cc \ rpcs.cc rpcsfactory.cc psitime.cc Enum.cc plpdirent.cc diff --git a/lib/plpdirent.cc b/lib/plpdirent.cc index 33e1a78..9695480 100644 --- a/lib/plpdirent.cc +++ b/lib/plpdirent.cc @@ -83,3 +83,141 @@ operator<<(ostream &o, const PlpDirent &e) { o.flags(old); return o; } + +PlpDrive::PlpDrive() { +} + +PlpDrive::PlpDrive(const PlpDrive &other) { +} + +void PlpDrive:: +setMediaType(u_int32_t type) { + mediatype = type; +} + +void PlpDrive:: +setDriveAttribute(u_int32_t attr) { + driveattr = attr; +} + +void PlpDrive:: +setMediaAttribute(u_int32_t attr) { + mediaattr = attr; +} + +void PlpDrive:: +setUID(u_int32_t attr) { + uid = attr; +} + +void PlpDrive:: +setSize(u_int32_t sizeLo, u_int32_t sizeHi) { + size = ((unsigned long long)sizeHi << 32) + sizeLo; +} + +void PlpDrive:: +setSpace(u_int32_t spaceLo, u_int32_t spaceHi) { + space = ((unsigned long long)spaceHi << 32) + spaceLo; +} + +void PlpDrive:: +setName(char drive, const char * const volname) { + drivechar = drive; + name = ""; + name += volname; +} + +u_int32_t PlpDrive:: +getMediaType() { + return mediatype; +} + +static const char * const media_types[] = { + "Not present", + "Unknown", + "Floppy", + "Disk", + "CD-ROM", + "RAM", + "Flash Disk", + "ROM", + "Remote", +}; + +void PlpDrive:: +getMediaType(string &ret) { + ret = media_types[mediatype]; +} + +u_int32_t PlpDrive:: +getDriveAttribute() { + return driveattr; +} + +static void +appendWithDelim(string &s1, const char * const s2) { + if (!s1.empty()) + s1 += ','; + s1 += s2; +} + +void PlpDrive:: +getDriveAttribute(string &ret) { + ret = ""; + if (driveattr & 1) + appendWithDelim(ret, "local"); + if (driveattr & 2) + appendWithDelim(ret, "ROM"); + if (driveattr & 4) + appendWithDelim(ret, "redirected"); + if (driveattr & 8) + appendWithDelim(ret, "substituted"); + if (driveattr & 16) + appendWithDelim(ret, "internal"); + if (driveattr & 32) + appendWithDelim(ret, "removable"); +} + +u_int32_t PlpDrive:: +getMediaAttribute() { + return mediaattr; +} + +void PlpDrive:: +getMediaAttribute(string &ret) { + ret = ""; + + if (mediaattr & 1) + appendWithDelim(ret, "variable size"); + if (mediaattr & 2) + appendWithDelim(ret, "dual density"); + if (mediaattr & 4) + appendWithDelim(ret, "formattable"); + if (mediaattr & 8) + appendWithDelim(ret, "write protected"); +} + +u_int32_t PlpDrive:: +getUID() { + return uid; +} + +u_int64_t PlpDrive:: +getSize() { + return size; +} + +u_int64_t PlpDrive:: +getSpace() { + return space; +} + +string PlpDrive:: +getName() { + return name; +} + +char PlpDrive:: +getDrivechar() { + return drivechar; +} diff --git a/lib/plpdirent.h b/lib/plpdirent.h index 9a25a67..c567a9b 100644 --- a/lib/plpdirent.h +++ b/lib/plpdirent.h @@ -157,4 +157,168 @@ private: string attrstr; string name; }; + +/** + * A class representing information about + * a Disk drive on the psion. An Object of this type + * is used by @ref rfsv::devinfo for returning the + * information of the probed drive. + * + * @author Fritz Elfert + */ +class PlpDrive { + friend rfsv32; + friend rfsv16; + + public: + /** + * Default constructor. + */ + PlpDrive(); + + /** + * Copy constructor + */ + PlpDrive(const PlpDrive &other); + + /** + * Retrieve the media type of the drive. + * + * @returns The media type of the probed drive. + *
+	 * Media types are encoded by a number
+         * in the range 0 .. 8 with the following
+	 * meaning:
+	 *
+	 *   0 = Not present
+	 *   1 = Unknown
+	 *   2 = Floppy
+	 *   3 = Disk
+	 *   4 = CD-ROM
+	 *   5 = RAM
+	 *   6 = Flash Disk
+	 *   7 = ROM
+	 *   8 = Remote
+	 * 
+ */ + u_int32_t getMediaType(); + + /** + * Retrieve the media type of the drive. + * Just like the above function, but returns + * the media type as human readable string. + * + * @param ret The string is returned here. + */ + void getMediaType(string &ret); + + /** + * Retrieve the attributes of the drive. + * + * @returns The attributes of the probed drive. + *
+	 * Drive attributes are encoded by a number
+	 * in the range 0 .. 63. The bits have the
+	 * the following meaning:
+	 *
+	 *   bit 0 = local
+	 *   bit 1 = ROM
+	 *   bit 2 = redirected
+	 *   bit 3 = substituted
+	 *   bit 4 = internal
+	 *   bit 5 = removable
+	 * 
+ */ + u_int32_t getDriveAttribute(); + + /** + * Retrieve the attributes of the drive. + * Just like the above function, but returns + * the attributes as human readable string. + * + * @param ret The string is returned here. + */ + void getDriveAttribute(string &ret); + + /** + * Retrieve the attributes of the media. + * + * @returns The attributes of the probed media. + *
+	 * Media attributes are encoded by a number
+	 * in the range 0 .. 15. The bits have the
+	 * following meaning:
+	 *
+	 *   bit 0 = variable size
+	 *   bit 1 = dual density
+	 *   bit 2 = formattable
+	 *   bit 3 = write protected
+	 * 
+ */ + u_int32_t getMediaAttribute(); + + /** + * Retrieve the attributes of the media. + * Just like the above function, but returns + * the attributes as human readable string. + * + * @param ret The string is returned here. + */ + void getMediaAttribute(string &ret); + + /** + * Retrieve the UID of the drive. + * Each drive, except the ROM drive on a Psion has + * a unique ID which can be retrieved here. + * + * @returns The UID of the probed drive. + */ + u_int32_t getUID(); + + /** + * Retrieve the total capacity of the drive. + * + * @returns The capacity of the probed drive in bytes. + */ + u_int64_t getSize(); + + /** + * Retrieve the free capacity on the drive. + * + * @returns The free space on the probed drive in bytes. + */ + u_int64_t getSpace(); + + /** + * Retrieve the volume name of the drive. + * + * returns The volume name of the drive. + */ + string getName(); + + /** + * Retrieve the drive letter of the drive. + * + * returns The letter of the probed drive. + */ + char getDrivechar(); + + private: + void setMediaType(u_int32_t type); + void setDriveAttribute(u_int32_t attr); + void setMediaAttribute(u_int32_t attr); + void setUID(u_int32_t uid); + void setSize(u_int32_t sizeLo, u_int32_t sizeHi); + void setSpace(u_int32_t spaceLo, u_int32_t spaceHi); + void setName(char drive, const char * const volname); + + u_int32_t mediatype; + u_int32_t driveattr; + u_int32_t mediaattr; + u_int32_t uid; + u_int64_t size; + u_int64_t space; + char drivechar; + string name; +}; #endif diff --git a/lib/ppsocket.cc b/lib/ppsocket.cc index a482ae5..9b0a33d 100644 --- a/lib/ppsocket.cc +++ b/lib/ppsocket.cc @@ -38,6 +38,7 @@ #include "bufferstore.h" #include "ppsocket.h" +#include "iowatch.h" #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 @@ -49,6 +50,7 @@ ppsocket::ppsocket(const ppsocket & another) m_PeerAddr = another.m_PeerAddr; m_Bound = another.m_Bound; m_LastError = another.m_LastError; + myWatch = another.myWatch; } @@ -64,21 +66,32 @@ ppsocket::ppsocket() m_Bound = false; m_LastError = 0; + myWatch = 0L; } ppsocket::~ppsocket() { if (m_Socket != INVALID_SOCKET) { - shutdown(m_Socket, 3); + if (myWatch) + myWatch->remIO(m_Socket); + shutdown(m_Socket, SHUT_RDWR); ::close(m_Socket); } } +void ppsocket:: +setWatch(IOWatch *watch) { + if (watch) + myWatch = watch; +} + bool ppsocket:: reconnect() { if (m_Socket != INVALID_SOCKET) { - shutdown(m_Socket, 3); + if (myWatch) + myWatch->remIO(m_Socket); + shutdown(m_Socket, SHUT_RDWR); ::close(m_Socket); } m_Socket = INVALID_SOCKET; @@ -94,6 +107,8 @@ reconnect() m_LastError = errno; return (false); } + if (myWatch) + myWatch->addIO(m_Socket); return (true); } @@ -148,6 +163,8 @@ connect(const char * const Peer, int PeerPort, const char * const Host, int Host m_LastError = errno; return (false); } + if (myWatch) + myWatch->addIO(m_Socket); return (true); } @@ -167,6 +184,8 @@ listen(const char * const Host, int Port) //* Listen on the port * //********************** + if (myWatch) + myWatch->addIO(m_Socket); if (::listen(m_Socket, 5) != 0) { m_LastError = errno; return (false); @@ -215,11 +234,9 @@ accept(string *Peer) // Make sure the new socket hasn't inherited O_NONBLOCK // from the accept socket - int flags = fcntl( accepted->m_Socket, F_GETFL, 0 ); - if( flags >= 0 ) { - flags &= ~O_NONBLOCK; - fcntl( accepted->m_Socket, F_SETFL, flags); - } + int flags = fcntl(accepted->m_Socket, F_GETFL, 0); + flags &= ~O_NONBLOCK; + fcntl(accepted->m_Socket, F_SETFL, flags); accepted->m_HostAddr = m_HostAddr; accepted->m_Bound = true; @@ -232,18 +249,22 @@ accept(string *Peer) if (peer) *Peer = peer; } + if (accepted && myWatch) { + accepted->setWatch(myWatch); + myWatch->addIO(accepted->m_Socket); + } return accepted; } bool ppsocket:: -dataToGet() const +dataToGet(int sec, int usec) const { fd_set io; FD_ZERO(&io); FD_SET(m_Socket, &io); struct timeval t; - t.tv_usec = 0; - t.tv_sec = 0; + t.tv_usec = usec; + t.tv_sec = sec; return (select(m_Socket + 1, &io, NULL, NULL, &t) != 0) ? true : false; } @@ -258,16 +279,15 @@ getBufferStore(bufferStore & a, bool wait) long count = 0; unsigned char *buff; unsigned char *bp; - if (!wait && !dataToGet()) + if (!wait && !dataToGet(0, 0)) return 0; a.init(); - - if (recv(&l, sizeof(l), 0) != sizeof(l)) + if (recv(&l, sizeof(l), MSG_NOSIGNAL) != sizeof(l)) return -1; l = ntohl(l); bp = buff = new unsigned char[l]; while (l > 0) { - int j = recv(bp, l, 0); + int j = recv(bp, l, MSG_NOSIGNAL); if (j == SOCKET_ERROR || j == 0) { delete[]buff; return -1; @@ -290,11 +310,15 @@ sendBufferStore(const bufferStore & a) int retries = 0; int i; - i = send((char *) &hl, sizeof(hl), 0); - if (i != sizeof(hl)) - return false; + bufferStore b; + b.addDWord(hl); + b.addBuff(a); +// i = send((char *)&hl, sizeof(hl), MSG_NOSIGNAL); +// if (i != sizeof(hl)) +// return false; + l += 4; while (l > 0) { - i = send((const char *)a.getString(sent), l, 0); + i = send((const char *)b.getString(sent), l, MSG_NOSIGNAL); if (i == SOCKET_ERROR || i == 0) return (false); sent += i; @@ -332,7 +356,9 @@ send(const void * const buf, int len, int flags) bool ppsocket:: closeSocket(void) { - shutdown(m_Socket, 3); + if (myWatch) + myWatch->remIO(m_Socket); + shutdown(m_Socket, SHUT_RDWR); if (::close(m_Socket) != 0) { m_LastError = errno; return false; diff --git a/lib/ppsocket.h b/lib/ppsocket.h index 57cc788..b8f7ebe 100644 --- a/lib/ppsocket.h +++ b/lib/ppsocket.h @@ -8,6 +8,7 @@ #include class bufferStore; +class IOWatch; /** * A class for dealing with sockets. @@ -80,11 +81,14 @@ public: ppsocket *accept(string *Peer); /** - * Check for incoming data. + * Check and optionally wait for incoming data. + * + * @param sec Timeout in seconds + * @param usec Timeout in microseconds * * @returns true if data is available, false otherwise. */ - bool dataToGet() const; + bool dataToGet(int sec, int usec) const; /** * Receive data into a @ref bufferStore . @@ -169,11 +173,13 @@ public: bool getHost(string *Host, int *Port); /** - * Retrieves the socket number. + * Registers an @ref IOWatch for this socket. + * This IOWatch gets the socket added/removed + * automatically. * - * @returns the socket number. + * @param watch The IOWatch to register. */ - inline int socket(void) const { return(m_Socket); } + void setWatch(IOWatch *watch); private: /** @@ -193,6 +199,7 @@ public: int m_Port; bool m_Bound; int m_LastError; + IOWatch *myWatch; }; #endif diff --git a/lib/rfsv.h b/lib/rfsv.h index 0cfe7b2..9125f01 100644 --- a/lib/rfsv.h +++ b/lib/rfsv.h @@ -10,6 +10,7 @@ typedef deque PlpDir; class ppsocket; +class PlpDrive; const int RFSV_SENDLEN = 2000; @@ -19,8 +20,20 @@ const int RFSV_SENDLEN = 2000; */ typedef int (*cpCallback_t)(void *, u_int32_t); +class rfsv16; +class rfsv32; + +/** + * A helper class for storing + * intermediate internal information in rfsv16 and + * rfsv32 . + * @internal + */ class rfsvDirhandle { - public: + friend rfsv16; + friend rfsv32; + + private: u_int32_t h; bufferStore b; }; @@ -330,15 +343,12 @@ class rfsv { * * @param dev An integer, representing the drive to get details from. * (0 represents A:, 1 is B: and so on ...) - * @param free On return, the free space in bytes is returned here. - * @param total On return, the total capacity in bytes is returned here. - * @param attr On return, the attributes of the drive are returned here. - * @param uniqueid On return, the unique Id of the drive is returned here. - * @param name On return, the volume name returned here. + * @param drive A @ref PlpDrive object which is filled with the drive's + * information upon return. * * @returns A Psion error code (One of enum @ref #errs ). */ - virtual Enum devinfo(const u_int32_t dev, u_int32_t &free, u_int32_t &total, u_int32_t &attr, u_int32_t &uniqueid, string &name) = 0; + virtual Enum devinfo(const u_int32_t dev, PlpDrive &drive) = 0; /** * Reads from a file on the Psion. diff --git a/lib/rfsv16.cc b/lib/rfsv16.cc index 2b474cb..f98816c 100644 --- a/lib/rfsv16.cc +++ b/lib/rfsv16.cc @@ -413,8 +413,18 @@ devlist(u_int32_t &devbits) return res; } +static int sibo_dattr[] = { + 1, // Unknown + 2, // Floppy + 3, // Disk + 6, // Flash + 5, // RAM + 7, // ROM + 7, // write-protected == ROM ? +}; + Enum rfsv16:: -devinfo(const u_int32_t devnum, u_int32_t &free, u_int32_t &size, u_int32_t &attr, u_int32_t &uniqueid, string &name) +devinfo(const u_int32_t devnum, PlpDrive &drive) { bufferStore a; Enum res; @@ -448,16 +458,31 @@ devinfo(const u_int32_t devnum, u_int32_t &free, u_int32_t &size, u_int32_t &att // cerr << "devinfo STATUSDEVICE res is " << dec << (signed short int) res << endl; return res; } + + int attr = a.getWord(2); + attr = sibo_dattr[a.getWord(2) & 0xff]; + drive.setMediaType(attr); + attr = a.getWord(2); - // int changeable = a.getWord(4); - size = a.getDWord(6); - free = a.getDWord(10); - // const char *volume = a.getString(14); - // int battery = a.getWord(30); - // const char *devicename = a.getString(62); - uniqueid = 0; - name = ""; - name += (char)(devnum + 'A'); + int changeable = a.getWord(4) ? 32 : 0; + int internal = (attr & 0x2000) ? 16 : 0; + + drive.setDriveAttribute(changeable | internal); + + int variable = (attr & 0x4000) ? 1 : 0; + int dualdens = (attr & 0x1000) ? 2 : 0; + int formattable = (attr & 0x0800) ? 4 : 0; + int protect = ((attr & 0xff) == 6) ? 8 : 0; + + drive.setMediaAttribute(variable|dualdens|formattable|protect); + + drive.setUID(0); + drive.setSize(a.getDWord(6), 0); + drive.setSpace(a.getDWord(10), 0); + + drive.setName('A' + devnum, a.getString(14)); + + return res; } diff --git a/lib/rfsv16.h b/lib/rfsv16.h index a94aa5f..42661f8 100644 --- a/lib/rfsv16.h +++ b/lib/rfsv16.h @@ -3,15 +3,19 @@ #include "rfsv.h" +class rfsvfactory; + /** * This is the implementation of the @ref rfsv protocol for - * Psion series 3 (SIBO) variant. - * For a complete documentation, see @ref rfsv . + * Psion series 3 (SIBO) variant. You normally never create + * objects of this class directly. Thus the constructor is + * private. Use @ref rfsvfactory for creating an instance of + * @ref rfsv . For a complete documentation, see @ref rfsv . */ class rfsv16 : public rfsv { -public: - rfsv16(ppsocket *); + friend rfsvfactory; +public: Enum fopen(const u_int32_t, const char * const, u_int32_t &); Enum mktemp(u_int32_t &, string &); Enum fcreatefile(const u_int32_t, const char * const, u_int32_t &); @@ -25,7 +29,7 @@ public: Enum fsetattr(const char * const, const u_int32_t seta, const u_int32_t unseta); Enum dircount(const char * const, u_int32_t &); Enum devlist(u_int32_t &); - Enum devinfo(const u_int32_t, u_int32_t &, u_int32_t &, u_int32_t &, u_int32_t &, string &); + Enum devinfo(const u_int32_t, PlpDrive &); Enum fread(const u_int32_t, unsigned char * const, const u_int32_t, u_int32_t &); Enum fwrite(const u_int32_t, const unsigned char * const, const u_int32_t, u_int32_t &); Enum copyFromPsion(const char * const, const char * const, void *, cpCallback_t); @@ -102,6 +106,11 @@ private: P_FAMASK = 0x0f3f /* All of the above */ }; + /** + * Private constructor. Shall be called by + * rfsvfactory only. + */ + rfsv16(ppsocket *); // Miscellaneous Enum fopendir(const char * const, u_int32_t &); diff --git a/lib/rfsv32.cc b/lib/rfsv32.cc index 74a1959..0b6f120 100644 --- a/lib/rfsv32.cc +++ b/lib/rfsv32.cc @@ -358,7 +358,7 @@ devlist(u_int32_t &devbits) } Enum rfsv32:: -devinfo(const u_int32_t dev, u_int32_t &free, u_int32_t &total, u_int32_t &attr, u_int32_t &uniqueid, string &name) +devinfo(const u_int32_t dev, PlpDrive &drive) { bufferStore a; Enum res; @@ -368,13 +368,14 @@ devinfo(const u_int32_t dev, u_int32_t &free, u_int32_t &total, u_int32_t &attr, return E_PSI_FILE_DISC; res = getResponse(a); if (res == E_PSI_GEN_NONE) { - attr = a.getDWord(0); - uniqueid = a.getDWord(16); - total = a.getDWord(20); - free = a.getDWord(28); - // vnamelen = a.getDWord(36); + drive.setMediaType(a.getDWord(0)); + drive.setDriveAttribute(a.getDWord(8)); + drive.setMediaAttribute(a.getDWord(12)); + drive.setUID(a.getDWord(16)); + drive.setSize(a.getDWord(20), a.getDWord(24)); + drive.setSpace(a.getDWord(28), a.getDWord(32)); a.addByte(0); - name = a.getString(40); + drive.setName('A' + dev, a.getString(40)); } return res; } diff --git a/lib/rfsv32.h b/lib/rfsv32.h index abbc6ad..4afb95a 100644 --- a/lib/rfsv32.h +++ b/lib/rfsv32.h @@ -4,16 +4,19 @@ #include "rfsv.h" #include "plpdirent.h" +class rfsvfactory; + /** * This is the implementation of the @ref rfsv protocol for - * Psion series 5 (EPOC) variant. - * For a complete documentation, see @ref rfsv . + * Psion series 5 (EPOC) variant. You normally never create + * objects of this class directly. Thus the constructor is + * private. Use @ref rfsvfactory for creating an instance of + * @ref rfsv . For a complete documentation, see @ref rfsv . */ class rfsv32 : public rfsv { + friend rfsvfactory; public: - rfsv32(ppsocket *); - Enum dir(const char * const, PlpDir &); Enum dircount(const char * const, u_int32_t &); Enum copyFromPsion(const char * const, const char * const, void *, cpCallback_t); @@ -39,7 +42,7 @@ public: Enum fclose(const u_int32_t); Enum devlist(u_int32_t &); - Enum devinfo(const u_int32_t, u_int32_t &, u_int32_t &, u_int32_t &, u_int32_t &, string &); + Enum devinfo(const u_int32_t, PlpDrive&); Enum opendir(const u_int32_t, const char * const, rfsvDirhandle &); Enum readdir(rfsvDirhandle &, PlpDirent &); Enum closedir(rfsvDirhandle &); @@ -155,6 +158,12 @@ private: REPLACE = 0x32 }; + /** + * Private constructor. Shall be called by + * rfsvfactory only. + */ + rfsv32(ppsocket *); + Enum err2psierr(int32_t); Enum fopendir(const u_int32_t, const char *, u_int32_t &); u_int32_t attr2std(const u_int32_t); diff --git a/lib/rfsvfactory.cc b/lib/rfsvfactory.cc index 12bd623..3699903 100644 --- a/lib/rfsvfactory.cc +++ b/lib/rfsvfactory.cc @@ -35,10 +35,20 @@ #include "rfsvfactory.h" #include "bufferstore.h" #include "ppsocket.h" -#include "bufferarray.h" +#include "Enum.h" + +ENUM_DEFINITION(rfsvfactory::errs, rfsvfactory::FACERR_NONE) { + stringRep.add(rfsvfactory::FACERR_NONE, "no error"); + stringRep.add(rfsvfactory::FACERR_COULD_NOT_SEND, "could not send version request"); + stringRep.add(rfsvfactory::FACERR_AGAIN, "try again"); + stringRep.add(rfsvfactory::FACERR_NOPSION, "no psion connected"); + stringRep.add(rfsvfactory::FACERR_PROTVERSION, "wrong protocol version"); + stringRep.add(rfsvfactory::FACERR_NORESPONSE, "no response from ncpd"); +} rfsvfactory::rfsvfactory(ppsocket *_skt) : serNum(0) { + err = FACERR_NONE; skt = _skt; } @@ -50,15 +60,19 @@ rfsv * rfsvfactory::create(bool reconnect) // so we can instantiate the correct RFSV protocol handler for the // caller. We announce ourselves to the NCP daemon, and the relevant // RFSV module will also announce itself. + bufferStore a; - a.init(); + + err = FACERR_NONE; a.addStringT("NCP$INFO"); if (!skt->sendBufferStore(a)) { if (!reconnect) - cerr << "rfsvfactory::create couldn't send version request" << endl; else { + err = FACERR_COULD_NOT_SEND; + else { skt->closeSocket(); serNum = 0; skt->reconnect(); + err = FACERR_AGAIN; } return NULL; } @@ -73,16 +87,13 @@ rfsv * rfsvfactory::create(bool reconnect) skt->closeSocket(); serNum = 0; skt->reconnect(); + err = FACERR_NOPSION; return NULL; } // Invalid protocol version - cerr << "rfsvfactory::create received odd protocol version from -ncpd! (" << a << ")" << endl; - } else { - cerr << "rfsvfactory::create sent, response not 1" << endl; - } + err = FACERR_PROTVERSION; + } else + err = FACERR_NORESPONSE; - // No message returned. return NULL; } - diff --git a/lib/rfsvfactory.h b/lib/rfsvfactory.h index 99136e3..8af4575 100644 --- a/lib/rfsvfactory.h +++ b/lib/rfsvfactory.h @@ -10,7 +10,20 @@ class ppsocket; * @ref rfsv protocol variant depending on the connected Psion. */ class rfsvfactory { + public: + /** + * The known errors which can happen during @ref create . + */ + enum errs { + FACERR_NONE = 0, + FACERR_COULD_NOT_SEND = 1, + FACERR_AGAIN = 2, + FACERR_NOPSION = 3, + FACERR_PROTVERSION = 4, + FACERR_NORESPONSE = 5, + }; + /** * Constructs a rfsvfactory. * @@ -30,6 +43,14 @@ class rfsvfactory { */ virtual rfsv * create(bool); + /** + * Retrieve an error code. + * + * @returns The error code, in case @ref create has + * failed, 0 otherwise. + */ + virtual Enum getError() { return err; } + private: /** * The socket to be used for connecting to the @@ -37,6 +58,7 @@ class rfsvfactory { */ ppsocket *skt; int serNum; + Enum err; }; #endif diff --git a/lib/rpcs16.h b/lib/rpcs16.h index 7085939..cc4d601 100644 --- a/lib/rpcs16.h +++ b/lib/rpcs16.h @@ -5,19 +5,25 @@ class ppsocket; class bufferStore; +class rpcsfactory; /** * This is the implementation of the @ref rpcs protocol for - * Psion series 3 (SIBO) variant. - * For a complete documentation, see @ref rpcs . + * Psion series 3 (SIBO) variant. You normally never create + * objects of this class directly. Thus the constructor is + * private. Use @ref rpcsfactory for creating an instance of + * @ref rpcs . For a complete documentation, see @ref rpcs . */ class rpcs16 : public rpcs { + friend rpcsfactory; + public: - rpcs16(ppsocket *); ~rpcs16(); Enum queryDrive(const char, bufferArray &); Enum getCmdLine(const char *, bufferStore &); + private: + rpcs16(ppsocket *); }; #endif diff --git a/lib/rpcs32.h b/lib/rpcs32.h index 0cab1b2..5230247 100644 --- a/lib/rpcs32.h +++ b/lib/rpcs32.h @@ -4,40 +4,45 @@ #include "rpcs.h" class ppsocket; +class rpcsfactory; /** * This is the implementation of the @ref rpcs protocol for - * Psion series 5 (EPOC) variant. - * For a complete documentation, see @ref rpcs . + * Psion series 5 (EPOC) variant. You normally never create + * objects of this class directly. Thus the constructor is + * private. Use @ref rpcsfactory for creating an instance of + * @ref rpcs . For a complete documentation, see @ref rpcs . */ class rpcs32 : public rpcs { - public: - rpcs32(ppsocket *); - ~rpcs32(); + friend rpcsfactory; - Enum queryDrive(const char, bufferArray &); - Enum getCmdLine(const char *, bufferStore &); - Enum getMachineInfo(machineInfo &); - Enum configOpen(void); - Enum configRead(void); + public: + ~rpcs32(); + + Enum queryDrive(const char, bufferArray &); + Enum getCmdLine(const char *, bufferStore &); + Enum getMachineInfo(machineInfo &); + Enum configOpen(void); + Enum configRead(void); #if 0 - Enum closeHandle(int); + Enum closeHandle(int); #endif - Enum regOpenIter(void); + Enum regOpenIter(void); #if 0 - Enum regReadIter(void); - Enum regWrite(void); - Enum regRead(void); - Enum regDelete(void); - Enum setTime(void); - Enum configOpen(void); - Enum configRead(void); - Enum configWrite(void); - Enum queryOpen(void); - Enum queryRead(void); - Enum quitServer(void); + Enum regReadIter(void); + Enum regWrite(void); + Enum regRead(void); + Enum regDelete(void); + Enum setTime(void); + Enum configOpen(void); + Enum configRead(void); + Enum configWrite(void); + Enum queryOpen(void); + Enum queryRead(void); + Enum quitServer(void); #endif - + private: + rpcs32(ppsocket *); }; #endif diff --git a/lib/rpcsfactory.cc b/lib/rpcsfactory.cc index 091f12a..bd3b77d 100644 --- a/lib/rpcsfactory.cc +++ b/lib/rpcsfactory.cc @@ -36,8 +36,20 @@ #include "bufferstore.h" #include "ppsocket.h" +#include "Enum.h" + +ENUM_DEFINITION(rpcsfactory::errs, rpcsfactory::FACERR_NONE) { + stringRep.add(rpcsfactory::FACERR_NONE, "no error"); + stringRep.add(rpcsfactory::FACERR_COULD_NOT_SEND, "could not send version request"); + stringRep.add(rpcsfactory::FACERR_AGAIN, "try again"); + stringRep.add(rpcsfactory::FACERR_NOPSION, "no psion connected"); + stringRep.add(rpcsfactory::FACERR_PROTVERSION, "wrong protocol version"); + stringRep.add(rpcsfactory::FACERR_NORESPONSE, "no response from ncpd"); +} + rpcsfactory::rpcsfactory(ppsocket *_skt) { + err = FACERR_NONE; skt = _skt; } @@ -49,15 +61,18 @@ rpcs * rpcsfactory::create(bool reconnect) // so we can instantiate the correct rpcs protocol handler for the // caller. We announce ourselves to the NCP daemon, and the relevant // rpcs module will also announce itself. + bufferStore a; - a.init(); + + err = FACERR_NONE; a.addStringT("NCP$INFO"); if (!skt->sendBufferStore(a)) { if (!reconnect) - cerr << "rpcsfactory::create couldn't send version request" << endl; + err = FACERR_COULD_NOT_SEND; else { skt->closeSocket(); skt->reconnect(); + err = FACERR_AGAIN; } return NULL; } @@ -71,13 +86,13 @@ rpcs * rpcsfactory::create(bool reconnect) if ((a.getLen() > 8) && !strncmp(a.getString(), "No Psion", 8)) { skt->closeSocket(); skt->reconnect(); + err = FACERR_NOPSION; return NULL; } // Invalid protocol version - cerr << "rpcsfactory::create received odd protocol version from ncpd! (" << a << ")" << endl; - } else { - cerr << "rpcsfactory::create sent, response not 1" << endl; - } + err = FACERR_PROTVERSION; + } else + err = FACERR_NORESPONSE; // No message returned. return NULL; diff --git a/lib/rpcsfactory.h b/lib/rpcsfactory.h index d57eb29..cc36f0d 100644 --- a/lib/rpcsfactory.h +++ b/lib/rpcsfactory.h @@ -11,6 +11,19 @@ class ppsocket; */ class rpcsfactory { public: + + /** + * The known errors which can happen during @ref create . + */ + enum errs { + FACERR_NONE = 0, + FACERR_COULD_NOT_SEND = 1, + FACERR_AGAIN = 2, + FACERR_NOPSION = 3, + FACERR_PROTVERSION = 4, + FACERR_NORESPONSE = 5, + }; + /** * Constructs a rpcsfactory. * @@ -30,12 +43,21 @@ class rpcsfactory { */ virtual rpcs * create(bool reconnect); + /** + * Retrieve an error code. + * + * @returns The error code, in case @ref create has + * failed, 0 otherwise. + */ + virtual Enum getError() { return err; } + private: /** * The socket to be used for connecting to the * ncpd daemon. */ ppsocket *skt; + Enum err; }; #endif -- cgit v1.2.3