diff --git a/.gitignore b/.gitignore index d5d661f..2875585 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ debug MasterCtrl.pro.user.2.7pre1 object_script.MasterCtrl.Debug object_script.MasterCtrl.Release +/.qmake.stash +/MasterCtrl.pro.user.3910d82.4.8-pre1 diff --git a/Configuration/Settings.mcs b/Configuration/Settings.mcs index 1445910..df599b1 100644 Binary files a/Configuration/Settings.mcs and b/Configuration/Settings.mcs differ diff --git a/MasterCtrl.pro b/MasterCtrl.pro index 694a1c0..fdd8a10 100644 --- a/MasterCtrl.pro +++ b/MasterCtrl.pro @@ -1,8 +1,12 @@ #QT += Network -QT += gui declarative network +#QT += gui declarative network +QT += gui network serialport +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets #CONFIG += console HEADERS += \ + Sources/Chalet/ChaletLoraDevice.h \ + Sources/Chalet/LoraDevice.h \ Sources/MasterCtrl.h \ Sources/GlobalDefine.h \ Sources/485NetworkCommIF.h \ @@ -28,9 +32,13 @@ HEADERS += \ Sources/Deadbolt/DeadboltDevice.h \ Sources/AvReceiver/AVReceiverDevice.h \ Sources/Sprinkler/SprinklerInterface.h \ - Sources/Sprinkler/SprinklerMgr.h + Sources/Sprinkler/SprinklerMgr.h \ + Sources/AvReceiver/AvReceiverInterface.h \ + Sources/AvReceiver/AvReceiverData.h SOURCES += \ + Sources/Chalet/ChaletLoraDevice.cpp \ + Sources/Chalet/LoraDevice.cpp \ Sources/main.cpp \ Sources/MasterCtrl.cpp \ Sources/485NetworkCommIF.cpp \ @@ -54,8 +62,11 @@ SOURCES += \ Sources/Deadbolt/DeadboltDevice.cpp \ Sources/AvReceiver/AVReceiverDevice.cpp \ Sources/Sprinkler/SprinklerInterface.cpp \ - Sources/Sprinkler/SprinklerMgr.cpp + Sources/Sprinkler/SprinklerMgr.cpp \ + Sources/AvReceiver/AvReceiverInterface.cpp \ + Sources/AvReceiver/AvReceiverData.cpp +DEFINES -= Q_OS_UNIX #win32:SOURCES += $$PWD/Source/qextserialport/win_qextserialport.cpp \ # $$PWD/Source/qextserialport/qextserialenumerator_win.cpp @@ -69,3 +80,8 @@ INCLUDEPATH += $$PWD/ \ $$PWD/Sources/Deadbolt \ $$PWD/Sources/Sprinkler \ $$PWD/Sources/AvReceiver \ + $$PWD/Sources/Chalet \ + +FORMS += + +DISTFILES += diff --git a/Sources/AvReceiver/AVReceiverDevice.cpp b/Sources/AvReceiver/AVReceiverDevice.cpp index 1815063..2969d9f 100644 --- a/Sources/AvReceiver/AVReceiverDevice.cpp +++ b/Sources/AvReceiver/AVReceiverDevice.cpp @@ -2,355 +2,67 @@ #include "GlobalDefine.h" #include "ProtocolDefs.h" + +/** + Command syntax + + @ SUBUNIT : FUNCNAME = Parameter [CR/LF] +[1] [2] [3] [4] [5] [6] [7] +[1] Start Delimiter (@) : The beginning of a command +[2] Sub Unit Name : Indicating whether the command is for System, any zones or +any internal input sources as iPod, Tuner, Sirius, and +Rhapsody etc +[3] Command Delimiter (:) : Sub Unit Name and Function name are separated by this +delimiter +[4] Function Name : Specifying actual operations, some of them are abbreviated +[5] Parameter Delimiter (=) : Separating the Function Name and its Parameter (Value) +[6] Parameter : Showing a parameter value of the command +[7] End Delimiter : The end of a command, Carriage +*/ + CAVReceiverDevice::CAVReceiverDevice() { mReceiverSocket = new QTcpSocket; + mDisconnectTimer = new QTimer; + mStateRequestTimer = new QTimer; + mDisconnectTimer->setSingleShot(true); + mDisconnectTimer->stop(); + + mStateRequestTimer->setSingleShot(true); + mStateRequestTimer->setInterval(RECEIVER_STATE_UPDATE_TIMEOUT); + + + connect(mDisconnectTimer,SIGNAL(timeout()),this,SLOT(DisconnectTimerExpired())); connect(mReceiverSocket,SIGNAL(connected()),this,SLOT(SocketConnected())); connect(mReceiverSocket,SIGNAL(disconnected()),this,SLOT(SocketDisconnected())); connect(mReceiverSocket,SIGNAL(readyRead()),this,SLOT(SocketRX())); - mInputsHash.insert(4,"DVD"); - mInputsHash.insert(25,"BD"); - mInputsHash.insert(5,"TV/SAT"); - mInputsHash.insert(15,"DVR/BDR"); - mInputsHash.insert(10,"VIDEO 1"); - mInputsHash.insert(14,"VIDEO 2"); - mInputsHash.insert(19,"HDMI 1"); - mInputsHash.insert(20,"HDMI 2"); - mInputsHash.insert(21,"HDMI 3"); - mInputsHash.insert(22,"HDMI 4"); - mInputsHash.insert(23,"HDMI 5"); - mInputsHash.insert(26,"INTERNET RADIO"); - mInputsHash.insert(17,"iPod/US"); - mInputsHash.insert(18,"XM RADIO"); - mInputsHash.insert(1,"CD"); - mInputsHash.insert(3,"CD-R/TAPE"); - mInputsHash.insert(2,"TUNER"); - mInputsHash.insert(0,"PHONO"); - mInputsHash.insert(12,"MULTI CH IN"); - mInputsHash.insert(33,"ADAPTER PORT"); - mInputsHash.insert(27,"SIRIUS"); - mInputsHash.insert(31,"HDMI (cyclic)"); - - - - //Listening mode SET strings - mListeningModesHash.insert(0x1,"STEREO (cyclic)"); - mListeningModesHash.insert(0x10,"STANDARD"); - mListeningModesHash.insert(0x9,"STEREO (direct set)"); - mListeningModesHash.insert(0x11,"(2ch source)"); - mListeningModesHash.insert(0x13,"PRO LOGIC2 MOVIE"); - mListeningModesHash.insert(0x18,"PRO LOGIC2x MOVIE"); - mListeningModesHash.insert(0x14,"PRO LOGIC2 MUSIC"); - mListeningModesHash.insert(0x19,"PRO LOGIC2x MUSIC"); - mListeningModesHash.insert(0x15,"PRO LOGIC2 GAME"); - mListeningModesHash.insert(0x20,"PRO LOGIC2x GAME"); - mListeningModesHash.insert(0x31,"PRO LOGIC2z HEIGHT"); - mListeningModesHash.insert(0x32,"WIDE SURROUND MOVIE"); - mListeningModesHash.insert(0x33,"WIDE SURROUND MUSIC"); - mListeningModesHash.insert(0x12,"PRO LOGIC"); - mListeningModesHash.insert(0x16,"Neo:6 CINEMA"); - mListeningModesHash.insert(0x17,"Neo:6 MUSIC"); - mListeningModesHash.insert(0x28,"XM HD SURROUND"); - mListeningModesHash.insert(0x29,"NEURAL SURROUND"); - mListeningModesHash.insert(0x37,"Neo:X CINEMA"); - mListeningModesHash.insert(0x38,"Neo:X MUSIC"); - mListeningModesHash.insert(0x39,"Neo:X GAME"); - mListeningModesHash.insert(0x40,"NEURAL SURROUND+Neo:X CINEMA"); - mListeningModesHash.insert(0x41,"NEURAL SURROUND+Neo:X MUSIC"); - mListeningModesHash.insert(0x42,"NEURAL SURROUND+Neo:X GAME"); - mListeningModesHash.insert(0x21,"(Multi ch source)"); - mListeningModesHash.insert(0x22,"(Multi ch source)+DOLBY EX"); - mListeningModesHash.insert(0x23,"(Multi ch source)+PRO LOGIC2x MOVIE"); - mListeningModesHash.insert(0x24,"(Multi ch source)+PRO LOGIC2x MUSIC"); - mListeningModesHash.insert(0x34,"(Multi-ch Source)+PRO LOGIC2z HEIGHT"); - mListeningModesHash.insert(0x35,"(Multi-ch Source)+WIDE SURROUND MOVIE"); - mListeningModesHash.insert(0x36,"(Multi-ch Source)+WIDE SURROUND MUSIC"); - mListeningModesHash.insert(0x25,"(Multi ch source)DTS-ES Neo:6"); - mListeningModesHash.insert(0x26,"(Multi ch source)DTS-ES matrix"); - mListeningModesHash.insert(0x27,"(Multi ch source)DTS-ES discrete"); - mListeningModesHash.insert(0x30,"(Multi ch source)DTS-ES 8ch discrete"); - mListeningModesHash.insert(0x43,"(Multi ch source)+Neo:X CINEMA"); - mListeningModesHash.insert(0x44,"(Multi ch source)+Neo:X MUSIC"); - mListeningModesHash.insert(0x45,"(Multi ch source)+Neo:X GAME"); - mListeningModesHash.insert(0x100,"ADVANCED SURROUND (cyclic)"); - mListeningModesHash.insert(0x101,"ACTION"); - mListeningModesHash.insert(0x103,"DRAMA"); - mListeningModesHash.insert(0x102,"SCI-FI"); - mListeningModesHash.insert(0x105,"MONO FILM"); - mListeningModesHash.insert(0x104,"ENTERTAINMENT SHOW"); - mListeningModesHash.insert(0x106,"EXPANDED THEATER"); - mListeningModesHash.insert(0x116,"TV SURROUND"); - mListeningModesHash.insert(0x118,"ADVANCED GAME"); - mListeningModesHash.insert(0x117,"SPORTS"); - mListeningModesHash.insert(0x107,"CLASSICAL"); - mListeningModesHash.insert(0x110,"ROCK/POP"); - mListeningModesHash.insert(0x109,"UNPLUGGED"); - mListeningModesHash.insert(0x112,"EXTENDED STEREO"); - mListeningModesHash.insert(0x3,"Front Stage Surround Advance Focus"); - mListeningModesHash.insert(0x4,"Front Stage Surround Advance Wide"); - mListeningModesHash.insert(0x153,"RETRIEVER AIR"); - mListeningModesHash.insert(0x113,"PHONES SURROUND"); - mListeningModesHash.insert(0x50,"THX (cyclic)"); - mListeningModesHash.insert(0x51,"PROLOGIC + THX CINEMA"); - mListeningModesHash.insert(0x52,"PL2 MOVIE + THX CINEMA"); - mListeningModesHash.insert(0x53,"Neo:6 CINEMA + THX CINEMA"); - mListeningModesHash.insert(0x54,"PL2x MOVIE + THX CINEMA"); - mListeningModesHash.insert(0x92,"PL2z HEIGHT + THX CINEMA"); - mListeningModesHash.insert(0x55,"THX SELECT2 GAMES"); - mListeningModesHash.insert(0x68,"THX CINEMA (for 2ch)"); - mListeningModesHash.insert(0x69,"THX MUSIC (for 2ch)"); - mListeningModesHash.insert(0x70,"THX GAMES (for 2ch)"); - mListeningModesHash.insert(0x71,"PL2 MUSIC + THX MUSIC"); - mListeningModesHash.insert(0x72,"PL2x MUSIC + THX MUSIC"); - mListeningModesHash.insert(0x93,"PL2z HEIGHT + THX MUSIC"); - mListeningModesHash.insert(0x73,"Neo:6 MUSIC + THX MUSIC"); - mListeningModesHash.insert(0x74,"PL2 GAME + THX GAMES"); - mListeningModesHash.insert(0x75,"PL2x GAME + THX GAMES"); - mListeningModesHash.insert(0x94,"PL2z HEIGHT + THX GAMES"); - mListeningModesHash.insert(0x76,"THX ULTRA2 GAMES"); - mListeningModesHash.insert(0x77,"PROLOGIC + THX MUSIC"); - mListeningModesHash.insert(0x78,"PROLOGIC + THX GAMES"); - mListeningModesHash.insert(0x201,"Neo:X CINEMA + THX CINEMA"); - mListeningModesHash.insert(0x202,"Neo:X MUSIC + THX MUSIC"); - mListeningModesHash.insert(0x203,"Neo:X GAME + THX GAMES"); - mListeningModesHash.insert(0x56,"THX CINEMA (for multi ch)"); - mListeningModesHash.insert(0x57,"THX SURROUND EX (for multi ch)"); - mListeningModesHash.insert(0x58,"PL2x MOVIE + THX CINEMA (for multi ch)"); - mListeningModesHash.insert(0x95,"PL2z HEIGHT + THX CINEMA (for multi ch)"); - mListeningModesHash.insert(0x59,"ES Neo:6 + THX CINEMA (for multi ch)"); - mListeningModesHash.insert(0x60,"ES MATRIX + THX CINEMA (for multi ch)"); - mListeningModesHash.insert(0x61,"ES DISCRETE + THX CINEMA (for multi ch)"); - mListeningModesHash.insert(0x67,"ES 8ch DISCRETE + THX CINEMA (for multi ch)"); - mListeningModesHash.insert(0x62,"THX SELECT2 CINEMA (for multi ch)"); - mListeningModesHash.insert(0x63,"THX SELECT2 MUSIC (for multi ch)"); - mListeningModesHash.insert(0x64,"THX SELECT2 GAMES (for multi ch)"); - mListeningModesHash.insert(0x65,"THX ULTRA2 CINEMA (for multi ch)"); - mListeningModesHash.insert(0x66,"THX ULTRA2 MUSIC (for multi ch)"); - mListeningModesHash.insert(0x79,"THX ULTRA2 GAMES (for multi ch)"); - mListeningModesHash.insert(0x80,"THX MUSIC (for multi ch)"); - mListeningModesHash.insert(0x81,"THX GAMES (for multi ch)"); - mListeningModesHash.insert(0x82,"PL2x MUSIC + THX MUSIC (for multi ch)"); - mListeningModesHash.insert(0x96,"PL2z HEIGHT + THX MUSIC (for multi ch)"); - mListeningModesHash.insert(0x83,"EX + THX GAMES (for multi ch)"); - mListeningModesHash.insert(0x97,"PL2z HEIGHT + THX GAMES (for multi ch)"); - mListeningModesHash.insert(0x84,"Neo:6 + THX MUSIC (for multi ch)"); - mListeningModesHash.insert(0x85,"Neo:6 + THX GAMES (for multi ch)"); - mListeningModesHash.insert(0x86,"ES MATRIX + THX MUSIC (for multi ch)"); - mListeningModesHash.insert(0x87,"ES MATRIX + THX GAMES (for multi ch)"); - mListeningModesHash.insert(0x88,"ES DISCRETE + THX MUSIC (for multi ch)"); - mListeningModesHash.insert(0x89,"ES DISCRETE + THX GAMES (for multi ch)"); - mListeningModesHash.insert(0x90,"ES 8CH DISCRETE + THX MUSIC (for multi ch)"); - mListeningModesHash.insert(0x91,"ES 8CH DISCRETE + THX GAMES (for multi ch)"); - mListeningModesHash.insert(0x204,"Neo:X CINEMA + THX CINEMA (for multi ch)"); - mListeningModesHash.insert(0x205,"Neo:X MUSIC + THX MUSIC (for multi ch)"); - mListeningModesHash.insert(0x206,"Neo:X GAME + THX GAMES (for multi ch)"); - mListeningModesHash.insert(0x5,"AUTO SURR/STREAM DIRECT (cyclic)"); - mListeningModesHash.insert(0x6,"AUTO SURROUND"); - mListeningModesHash.insert(0x151,"Auto Level Control (A.L.C.)"); - mListeningModesHash.insert(0x7,"DIRECT"); - mListeningModesHash.insert(0x8,"PURE DIRECT"); - mListeningModesHash.insert(0x152,"OPTIMUM SURROUND"); - - - mPlayingLMHash.insert(0x0101,"[)(]PLIIx MOVIE"); - mPlayingLMHash.insert(0x0102,"[)(]PLII MOVIE"); - mPlayingLMHash.insert(0x0103,"[)(]PLIIx MUSIC"); - mPlayingLMHash.insert(0x0104,"[)(]PLII MUSIC"); - mPlayingLMHash.insert(0x0105,"[)(]PLIIx GAME"); - mPlayingLMHash.insert(0x0106,"[)(]PLII GAME"); - mPlayingLMHash.insert(0x0107,"[)(]PROLOGIC"); - mPlayingLMHash.insert(0x0108,"Neo:6 CINEMA"); - mPlayingLMHash.insert(0x0109,"Neo:6 MUSIC"); - mPlayingLMHash.insert(0x010a,"XM HD Surround"); - mPlayingLMHash.insert(0x010b,"NEURAL SURR"); - mPlayingLMHash.insert(0x010c,"2ch Straight Decode"); - mPlayingLMHash.insert(0x010d,"[)(]PLIIz HEIGHT"); - mPlayingLMHash.insert(0x010e,"WIDE SURR MOVIE"); - mPlayingLMHash.insert(0x010f,"WIDE SURR MUSIC"); - mPlayingLMHash.insert(0x0110,"STEREO"); - mPlayingLMHash.insert(0x0111,"Neo:X CINEMA"); - mPlayingLMHash.insert(0x0112,"Neo:X MUSIC"); - mPlayingLMHash.insert(0x0113,"Neo:X GAME"); - mPlayingLMHash.insert(0x0114,"NEURAL SURROUND+Neo:X CINEMA"); - mPlayingLMHash.insert(0x0115,"NEURAL SURROUND+Neo:X MUSIC"); - mPlayingLMHash.insert(0x0116,"NEURAL SURROUND+Neo:X GAMES"); - mPlayingLMHash.insert(0x1101,"[)(]PLIIx MOVIE"); - mPlayingLMHash.insert(0x1102,"[)(]PLIIx MUSIC"); - mPlayingLMHash.insert(0x1103,"[)(]DIGITAL EX"); - mPlayingLMHash.insert(0x1104,"DTS +Neo:6 / DTS-HD +Neo:6"); - mPlayingLMHash.insert(0x1105,"ES MATRIX"); - mPlayingLMHash.insert(0x1106,"ES DISCRETE"); - mPlayingLMHash.insert(0x1107,"DTS-ES 8ch"); - mPlayingLMHash.insert(0x1108,"multi ch Straight Decode"); - mPlayingLMHash.insert(0x1109,"[)(]PLIIz HEIGHT"); - mPlayingLMHash.insert(0x110a,"WIDE SURR MOVIE"); - mPlayingLMHash.insert(0x110b,"WIDE SURR MUSIC"); - mPlayingLMHash.insert(0x110c,"Neo:X CINEMA"); - mPlayingLMHash.insert(0x110d,"Neo:X MUSIC"); - mPlayingLMHash.insert(0x110e,"Neo:X GAME"); - mPlayingLMHash.insert(0x0201,"ACTION"); - mPlayingLMHash.insert(0x0202,"DRAMA"); - mPlayingLMHash.insert(0x0203,"SCI-FI"); - mPlayingLMHash.insert(0x0204,"MONOFILM"); - mPlayingLMHash.insert(0x0205,"ENT.SHOW"); - mPlayingLMHash.insert(0x0206,"EXPANDED"); - mPlayingLMHash.insert(0x0207,"TV SURROUND"); - mPlayingLMHash.insert(0x0208,"ADVANCEDGAME"); - mPlayingLMHash.insert(0x0209,"SPORTS"); - mPlayingLMHash.insert(0x020a,"CLASSICAL"); - mPlayingLMHash.insert(0x020b,"ROCK/POP"); - mPlayingLMHash.insert(0x020c,"UNPLUGGED"); - mPlayingLMHash.insert(0x020d,"EXT.STEREO"); - mPlayingLMHash.insert(0x020e,"PHONES SURR."); - mPlayingLMHash.insert(0x020f,"FRONT STAGE SURROUND ADVANCE FOCUS"); - mPlayingLMHash.insert(0x0210,"FRONT STAGE SURROUND ADVANCE WIDE"); - mPlayingLMHash.insert(0x0211,"SOUND RETRIEVER AIR"); - mPlayingLMHash.insert(0x0301,"[)(]PLIIx MOVIE +THX"); - mPlayingLMHash.insert(0x0302,"[)(]PLII MOVIE +THX"); - mPlayingLMHash.insert(0x0303,"[)(]PL +THX CINEMA"); - mPlayingLMHash.insert(0x0304,"Neo:6 CINEMA +THX"); - mPlayingLMHash.insert(0x0305,"THX CINEMA"); - mPlayingLMHash.insert(0x0306,"[)(]PLIIx MUSIC +THX"); - mPlayingLMHash.insert(0x0307,"[)(]PLII MUSIC +THX"); - mPlayingLMHash.insert(0x0308,"[)(]PL +THX MUSIC"); - mPlayingLMHash.insert(0x0309,"Neo:6 MUSIC +THX"); - mPlayingLMHash.insert(0x030a,"THX MUSIC"); - mPlayingLMHash.insert(0x030b,"[)(]PLIIx GAME +THX"); - mPlayingLMHash.insert(0x030c,"[)(]PLII GAME +THX"); - mPlayingLMHash.insert(0x030d,"[)(]PL +THX GAMES"); - mPlayingLMHash.insert(0x030e,"THX ULTRA2 GAMES"); - mPlayingLMHash.insert(0x030f,"THX SELECT2 GAMES"); - mPlayingLMHash.insert(0x0310,"THX GAMES"); - mPlayingLMHash.insert(0x0311,"[)(]PLIIz +THX CINEMA"); - mPlayingLMHash.insert(0x0312,"[)(]PLIIz +THX MUSIC"); - mPlayingLMHash.insert(0x0313,"[)(]PLIIz +THX GAMES"); - mPlayingLMHash.insert(0x0314,"Neo:X CINEMA + THX CINEMA"); - mPlayingLMHash.insert(0x0315,"Neo:X MUSIC + THX MUSIC"); - mPlayingLMHash.insert(0x0316,"Neo:X GAMES + THX GAMES"); - mPlayingLMHash.insert(0x1301,"THX Surr EX"); - mPlayingLMHash.insert(0x1302,"Neo:6 +THX CINEMA"); - mPlayingLMHash.insert(0x1303,"ES MTRX +THX CINEMA"); - mPlayingLMHash.insert(0x1304,"ES DISC +THX CINEMA"); - mPlayingLMHash.insert(0x1305,"ES 8ch +THX CINEMA"); - mPlayingLMHash.insert(0x1306,"[)(]PLIIx MOVIE +THX"); - mPlayingLMHash.insert(0x1307,"THX ULTRA2 CINEMA"); - mPlayingLMHash.insert(0x1308,"THX SELECT2 CINEMA"); - mPlayingLMHash.insert(0x1309,"THX CINEMA"); - mPlayingLMHash.insert(0x130a,"Neo:6 +THX MUSIC"); - mPlayingLMHash.insert(0x130b,"ES MTRX +THX MUSIC"); - mPlayingLMHash.insert(0x130c,"ES DISC +THX MUSIC"); - mPlayingLMHash.insert(0x130d,"ES 8ch +THX MUSIC"); - mPlayingLMHash.insert(0x130e,"[)(]PLIIx MUSIC +THX"); - mPlayingLMHash.insert(0x130f,"THX ULTRA2 MUSIC"); - mPlayingLMHash.insert(0x1310,"THX SELECT2 MUSIC"); - mPlayingLMHash.insert(0x1311,"THX MUSIC"); - mPlayingLMHash.insert(0x1312,"Neo:6 +THX GAMES"); - mPlayingLMHash.insert(0x1313,"ES MTRX +THX GAMES"); - mPlayingLMHash.insert(0x1314,"ES DISC +THX GAMES"); - mPlayingLMHash.insert(0x1315,"ES 8ch +THX GAMES"); - mPlayingLMHash.insert(0x1316,"[)(]EX +THX GAMES"); - mPlayingLMHash.insert(0x1317,"THX ULTRA2 GAMES"); - mPlayingLMHash.insert(0x1318,"THX SELECT2 GAMES"); - mPlayingLMHash.insert(0x1319,"THX GAMES"); - mPlayingLMHash.insert(0x131a,"[)(]PLIIz +THX CINEMA"); - mPlayingLMHash.insert(0x131b,"[)(]PLIIz +THX MUSIC"); - mPlayingLMHash.insert(0x131c,"[)(]PLIIz +THX GAMES"); - mPlayingLMHash.insert(0x131d,"Neo:X CINEMA + THX CINEMA"); - mPlayingLMHash.insert(0x131e,"Neo:X MUSIC + THX MUSIC"); - mPlayingLMHash.insert(0x131f,"Neo:X GAME + THX GAMES"); - mPlayingLMHash.insert(0x0401,"STEREO"); - mPlayingLMHash.insert(0x0402,"[)(]PLII MOVIE"); - mPlayingLMHash.insert(0x0403,"[)(]PLIIx MOVIE"); - mPlayingLMHash.insert(0x0404,"Neo:6 CINEMA"); - mPlayingLMHash.insert(0x0405,"AUTO SURROUND Straight Decode"); - mPlayingLMHash.insert(0x0406,"[)(]DIGITAL EX"); - mPlayingLMHash.insert(0x0407,"[)(]PLIIx MOVIE"); - mPlayingLMHash.insert(0x0408,"DTS +Neo:6"); - mPlayingLMHash.insert(0x0409,"ES MATRIX"); - mPlayingLMHash.insert(0x040a,"ES DISCRETE"); - mPlayingLMHash.insert(0x040b,"DTS-ES 8ch"); - mPlayingLMHash.insert(0x040c,"XM HD Surround"); - mPlayingLMHash.insert(0x040d,"NEURAL SURR"); - mPlayingLMHash.insert(0x040e,"RETRIEVER AIR"); - mPlayingLMHash.insert(0x040f,"Neo:X CINEMA"); - mPlayingLMHash.insert(0x0410,"Neo:X CINEMA"); - mPlayingLMHash.insert(0x0501,"STEREO"); - mPlayingLMHash.insert(0x0502,"[)(]PLII MOVIE"); - mPlayingLMHash.insert(0x0503,"[)(]PLIIx MOVIE"); - mPlayingLMHash.insert(0x0504,"Neo:6 CINEMA"); - mPlayingLMHash.insert(0x0505,"ALC Straight Decode"); - mPlayingLMHash.insert(0x0506,"[)(]DIGITAL EX"); - mPlayingLMHash.insert(0x0507,"[)(]PLIIx MOVIE"); - mPlayingLMHash.insert(0x0508,"DTS +Neo:6"); - mPlayingLMHash.insert(0x0509,"ES MATRIX"); - mPlayingLMHash.insert(0x050a,"ES DISCRETE"); - mPlayingLMHash.insert(0x050b,"DTS-ES 8ch"); - mPlayingLMHash.insert(0x050c,"XM HD Surround"); - mPlayingLMHash.insert(0x050d,"NEURAL SURR"); - mPlayingLMHash.insert(0x050e,"RETRIEVER AIR"); - mPlayingLMHash.insert(0x050f,"Neo:X CINEMA"); - mPlayingLMHash.insert(0x0510,"Neo:X CINEMA"); - mPlayingLMHash.insert(0x0601,"STEREO"); - mPlayingLMHash.insert(0x0602,"[)(]PLII MOVIE"); - mPlayingLMHash.insert(0x0603,"[)(]PLIIx MOVIE"); - mPlayingLMHash.insert(0x0604,"Neo:6 CINEMA"); - mPlayingLMHash.insert(0x0605,"STREAM DIRECT NORMAL Straight Decode"); - mPlayingLMHash.insert(0x0606,"[)(]DIGITAL EX"); - mPlayingLMHash.insert(0x0607,"[)(]PLIIx MOVIE"); - mPlayingLMHash.insert(0x0608,"(nothing)"); - mPlayingLMHash.insert(0x0609,"ES MATRIX"); - mPlayingLMHash.insert(0x060a,"ES DISCRETE"); - mPlayingLMHash.insert(0x060b,"DTS-ES 8ch"); - mPlayingLMHash.insert(0x060c,"Neo:X CINEMA"); - mPlayingLMHash.insert(0x060d,"Neo:X CINEMA"); - mPlayingLMHash.insert(0x0701,"STREAM DIRECT PURE 2ch"); - mPlayingLMHash.insert(0x0702,"[)(]PLII MOVIE"); - mPlayingLMHash.insert(0x0703,"[)(]PLIIx MOVIE"); - mPlayingLMHash.insert(0x0704,"Neo:6 CINEMA"); - mPlayingLMHash.insert(0x0705,"STREAM DIRECT PURE Straight Decode"); - mPlayingLMHash.insert(0x0706,"[)(]DIGITAL EX"); - mPlayingLMHash.insert(0x0707,"[)(]PLIIx MOVIE"); - mPlayingLMHash.insert(0x0708,"(nothing)"); - mPlayingLMHash.insert(0x0709,"ES MATRIX"); - mPlayingLMHash.insert(0x070a,"ES DISCRETE"); - mPlayingLMHash.insert(0x070b,"DTS-ES 8ch"); - mPlayingLMHash.insert(0x070c,"Neo:X CINEMA"); - mPlayingLMHash.insert(0x070d,"Neo:X CINEMA"); - mPlayingLMHash.insert(0x0881,"OPTIMUM"); - mPlayingLMHash.insert(0x0e01,"HDMI THROUGH"); - mPlayingLMHash.insert(0x0f01,"MULTI CH IN"); - - mSpeakerStatusHash.insert(0,"SPEAKERS OFF"); - mSpeakerStatusHash.insert(1,"SPEAKER A ON"); - mSpeakerStatusHash.insert(2,"SPEAKER B ON"); - mSpeakerStatusHash.insert(3,"SPEAKERS A+B ON"); - - mHDMIOutSelectHash.insert(0,"HDMI ALL"); - mHDMIOutSelectHash.insert(1,"HDMI 1"); - mHDMIOutSelectHash.insert(2,"HDMI 2"); - mHDMIOutSelectHash.insert(3,"HDMI (cyclic)"); - + connect(mStateRequestTimer,SIGNAL(timeout()),this,SLOT(StateRequestTimerExpired())); } - - - CAVReceiverDevice::~CAVReceiverDevice() { mReceiverSocket->disconnectFromHost(); mReceiverSocket->waitForDisconnected(); delete mReceiverSocket; + delete mDisconnectTimer; + delete mStateRequestTimer; +} + +int CAVReceiverDevice::Start() +{ + mStateRequestTimer->start(); + return RET_OK; } int CAVReceiverDevice::ConnectToReceiver() { if(mReceiverSocket->state() != QAbstractSocket::ConnectedState) { - mReceiverSocket->connectToHost(RECEIVER_IP_ADDRESS,RECEIVER_PORT); + mReceiverSocket->connectToHost("192.168.50.101",50000); } return RET_OK; @@ -376,188 +88,128 @@ int CAVReceiverDevice::AnalyseRxData(QByteArray data) QStringList Commands = Data.split("\r\n",QString::SkipEmptyParts); - for(int i = 0; i < Commands.size(); i++) + + for(int i = 0; istate() == QAbstractSocket::ConnectedState) + { + mReceiverSocket->write(Command.toUtf8()); +// qDebug("Sent command to receiver : %s",qPrintable(mPendingCommand)); + } + else + { + mPendingCommand = Command; + ConnectToReceiver(); } return RET_OK; } @@ -565,16 +217,168 @@ int CAVReceiverDevice::AnalyseRxData(QByteArray data) void CAVReceiverDevice::SocketConnected() { - qDebug("Receiver Connected"); + if(mPendingCommand.isEmpty() == false) + { + QByteArray data =mPendingCommand.toLatin1(); + int ret = mReceiverSocket->write(data); +// qDebug("Sent command to receiver : %s",qPrintable(mPendingCommand)); + mPendingCommand.clear(); + return; + } + + qDebug("Receiver Connected"); } void CAVReceiverDevice::SocketDisconnected() { - qDebug("Receiver Disconnected"); +// qDebug("Receiver Disconnected"); } void CAVReceiverDevice::SocketRX() { - AnalyseRxData(mReceiverSocket->readAll()); + // qDebug("Receiver response:"); + QByteArray Data = mReceiverSocket->readAll(); +// qDebug("%s",qPrintable(Data)); + AnalyseRxData(Data); } + +void CAVReceiverDevice::DisconnectTimerExpired() +{ + DisconnectReceiver(); + mDisconnectTimer->stop(); +} + +int CAVReceiverDevice::DisconnectReceiverDelayed(int Delay) +{ + if(Delay > 5000) + { + Delay = 5000; + } + + mDisconnectTimer->start(Delay); + + return RET_OK; +} + +void CAVReceiverDevice::StateRequestTimerExpired() +{ + if(mReceiverSocket->state() != QAbstractSocket::ConnectedState) + { + SendReceiverCommand("@MAIN:BASIC=?"); + mStateRequestTimer->start(RECEIVER_STATE_UPDATE_TIMEOUT); + DisconnectReceiverDelayed(1000); + } + else + { + //A transaction is going on... wait and retry later + mStateRequestTimer->start(500); + } +} + +////// Network Interface Implementation + +int CAVReceiverDevice::SetSpeakerB(bool OnOff) +{ + QString Cmd = "@MAIN:SPEAKERB="; + if(OnOff) + { + Cmd += "On"; + } + else + Cmd += "Off"; + + SendReceiverCommand(Cmd); + DisconnectReceiverDelayed(); + return RET_OK; +} + +int CAVReceiverDevice::SetSpeakerA(bool OnOff) +{ + QString Cmd = "@MAIN:SPEAKERA="; + if(OnOff) + { + Cmd += "On"; + } + else + Cmd += "Off"; + + SendReceiverCommand(Cmd); + DisconnectReceiverDelayed(); + return RET_OK; +} +int CAVReceiverDevice::SetSpeakers(int SpeakerA, int SpeakerB) +{ + //First, speaker A. + if(SpeakerA != RECEIVER_DONT_CHANGE_SPK) + { + QString Cmd = "@MAIN:SPEAKERA="; + if(SpeakerA == RECEIVER_SET_SPK_ON) + { + Cmd += "On"; + } + else if(SpeakerA == RECEIVER_SET_SPK_OFF) + { + Cmd += "Off"; + } + else if(SpeakerA == RECEVIVER_TOGGLE_SPK) + { + if(mReceiverStatus.mSpeakerAState == true) + { + Cmd += "Off"; + } + else + { + Cmd += "On"; + } + } + else + { + qDebug("Got a SetSpeakers() command with invalid parameter for Speaker A. Weirds stuff!!"); + } + + SendReceiverCommand(Cmd); + } + + //Then, speaker B. + if(SpeakerB != RECEIVER_DONT_CHANGE_SPK) + { + QString Cmd = "@MAIN:SPEAKERB="; + if(SpeakerB == RECEIVER_SET_SPK_ON) + { + Cmd += "On"; + } + else if(SpeakerB == RECEIVER_SET_SPK_OFF) + { + Cmd += "Off"; + } + else if(SpeakerB == RECEVIVER_TOGGLE_SPK) + { + if(mReceiverStatus.mSpeakerAState == true) + { + Cmd += "Off"; + } + else + { + Cmd += "On"; + } + } + else + { + qDebug("Got a SetSpeakers() command with invalid parameter for Speaker B. Weirds stuff!!"); + } + + SendReceiverCommand(Cmd); + } + DisconnectReceiverDelayed(); + + return RET_OK; +} + +int CAVReceiverDevice::SendRawCommand(QString Cmd) +{ + return SendReceiverCommand(Cmd); + DisconnectReceiverDelayed(2000); + +} + diff --git a/Sources/AvReceiver/AVReceiverDevice.h b/Sources/AvReceiver/AVReceiverDevice.h index 7ddfd85..8d44d41 100644 --- a/Sources/AvReceiver/AVReceiverDevice.h +++ b/Sources/AvReceiver/AVReceiverDevice.h @@ -4,9 +4,13 @@ #include #include #include "NetworkDevice.h" +#include +#include +#include "AvReceiverData.h" -#define RECEIVER_PORT 23 -#define RECEIVER_IP_ADDRESS "192.168.0.104" +#define RECEIVER_PORT 50000 +#define RECEIVER_IP_ADDRESS "192.168.50.101" +#define RECEIVER_STATE_UPDATE_TIMEOUT 3000 enum eReceiverSpkStatus { @@ -17,6 +21,33 @@ enum eReceiverSpkStatus RECEIVER_UNKNOWN_SPK_STATUS }; +enum eSpkSetStateCmds +{ + RECEIVER_SET_SPK_OFF, + RECEIVER_SET_SPK_ON, + RECEVIVER_TOGGLE_SPK, + RECEIVER_DONT_CHANGE_SPK +}; + +enum eReceiverSubUnits +{ + SYS, + MAIN, + TUN, + SIRIUS, + IPOD, + BT, + UAW, + RHAP, + SIRIUSIR, + PANDORA, + NAPSTER, + PC, + NETRADIO, + USB, + IPODUSB +}; + class CAVReceiverDevice : QObject { Q_OBJECT @@ -24,35 +55,40 @@ class CAVReceiverDevice : QObject public: CAVReceiverDevice(); ~CAVReceiverDevice(); + int Start(); + +private: int ConnectToReceiver(); int DisconnectReceiver(); + int DisconnectReceiverDelayed(int Delay = 500); + int SendReceiverCommand(QString Command); + int UpdateReceiverStateParam(QString SubUnit, QString Fcn, QString Param); +public: + //Network Interface Implementation + int SetSpeakerB(bool OnOff); + int SetSpeakerA(bool OnOff); + int SetSpeakers(int SpeakerA, int SpeakerB); + int SendRawCommand(QString Cmd); + CAvReceiverMainStatus GetReceiverStatus(){return mReceiverStatus;} private: QTcpSocket *mReceiverSocket; int AnalyseRxData(QByteArray data); - - int mReceiverVolume; - bool mReceiverMute; - int mReceiverCurInput; - int mReceiverListeningModeSet; - int mReceiverPlayingLM; - int mReceiverSpkStatus; - int mReceiverHDMIOutSel; - - QHash mInputsHash; - QHash mListeningModesHash; - QHash mPlayingLMHash; - QHash mSpeakerStatusHash; - QHash mHDMIOutSelectHash; + QTimer *mDisconnectTimer, *mStateRequestTimer; + CAvReceiverMainStatus mReceiverStatus; bool mIsConnected; + QString mPendingCommand; + public slots: void SocketConnected(); void SocketDisconnected(); void SocketRX(); + void DisconnectTimerExpired(); + void StateRequestTimerExpired(); }; #endif // AVRECEIVERDEVICE_H diff --git a/Sources/AvReceiver/AvReceiverData.cpp b/Sources/AvReceiver/AvReceiverData.cpp new file mode 100644 index 0000000..f8ace7a --- /dev/null +++ b/Sources/AvReceiver/AvReceiverData.cpp @@ -0,0 +1,52 @@ +#include "AvReceiverData.h" +#include + +CAvReceiverMainStatus::CAvReceiverMainStatus() +{ + mDataValid = false; + mReceiverOnline = false; +} + +QByteArray CAvReceiverMainStatus::ToByteArray() +{ + + QByteArray Output; + Output.clear(); + QDataStream Strm(&Output,QIODevice::WriteOnly); + + Strm << mMainPwrStatus; + Strm << mMainSleepStatus; + Strm << mMainVolume; + Strm << mIsMute; + Strm << mInput; + Strm << mProgram; + Strm << mSpeakerAState; + Strm << mSpeakerBState; + + Strm << mDataValid; + Strm << mReceiverOnline; + + return Output; + +} + +int CAvReceiverMainStatus::FromByteArray(QByteArray Data) +{ + QDataStream Strm(Data); + Strm.device()->seek(0); + + Strm >> mMainPwrStatus; + Strm >> mMainSleepStatus; + Strm >> mMainVolume; + Strm >> mIsMute; + Strm >> mInput; + Strm >> mProgram; + Strm >> mSpeakerAState; + Strm >> mSpeakerBState; + + Strm >> mDataValid; + Strm >> mReceiverOnline; + + return RET_OK; + +} diff --git a/Sources/AvReceiver/AvReceiverData.h b/Sources/AvReceiver/AvReceiverData.h new file mode 100644 index 0000000..28c4c02 --- /dev/null +++ b/Sources/AvReceiver/AvReceiverData.h @@ -0,0 +1,30 @@ +#ifndef AVRECEIVERDATA_H +#define AVRECEIVERDATA_H +#include +#include "GlobalDefine.h" + + +class CAvReceiverMainStatus +{ +public: + + QByteArray ToByteArray(); + int FromByteArray(QByteArray Data); + + CAvReceiverMainStatus(); + + bool mMainPwrStatus; + bool mMainSleepStatus; + float mMainVolume; + bool mIsMute; + QString mInput; + QString mProgram; + bool mSpeakerAState; + bool mSpeakerBState; + + bool mDataValid; + bool mReceiverOnline; + +}; + +#endif // AVRECEIVERDATA_H diff --git a/Sources/AvReceiver/AvReceiverInterface.cpp b/Sources/AvReceiver/AvReceiverInterface.cpp new file mode 100644 index 0000000..83e0fa4 --- /dev/null +++ b/Sources/AvReceiver/AvReceiverInterface.cpp @@ -0,0 +1,71 @@ +#include "AvReceiverInterface.h" +#include "ProtocolDefs.h" +#include "AVReceiverDevice.h" + +CAvReceiverInterface::CAvReceiverInterface(int Address, CAbstractNetworkCommIF *NetworkInterface , CAVReceiverDevice *DevicePtr): + CNetworkDevice(ID_AVRECEIVER_INTERFACE,Address,NetworkInterface) +{ + mAvReceiverDevice = DevicePtr; +} + +int CAvReceiverInterface::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data) +{ + Q_UNUSED(DeviceID) + Q_UNUSED(DeviceAddress) + Q_UNUSED(DataSize) + Q_UNUSED(Data) + + switch(MessageID) + { + case AV_RECEIVER_INTERFACE_ACK: + { + break; + } + case AV_RECEIVER_INTERFACE_GENERAL_STATUS_REQUEST: + { + QByteArray data = mAvReceiverDevice->GetReceiverStatus().ToByteArray(); + mNetworkInterfacePtr->SendNetworkMessage(ID_AVRECEIVER_INTERFACE,mDeviceAddress,AV_RECEIVER_INTERFACE_GENERAL_STATUS_RESPONSE,data.size(),data); + break; + } + + case AV_RECEIVER_INTERFACE_SET_MAIN_POWER_REQUEST: + { + break; + } + case AV_RECEIVER_INTERFACE_SET_SPEAKERB_REQUEST: + { + bool SpkStatus = (bool)Data[0]; + mAvReceiverDevice->SetSpeakerB(SpkStatus); + break; + } + case AV_RECEIVER_INTERFACE_SET_SPEAKERA_REQUEST: + { + bool SpkStatus = (bool)Data[0]; + mAvReceiverDevice->SetSpeakerA(SpkStatus); + break; + + } + case AV_RECEIVER_INTERFACE_SET_SPEAKERS_REQUEST: + { + break; + } + case AV_RECEIVER_INTERFACE_SEND_DIRECT_CMD_REQUEST: + { + break; + } + case AV_RECEIVER_INTERFACE_GENERAL_STATUS_RESPONSE: + case AV_RECEIVER_INTERFACE_SET_MAIN_POWER_RESPONSE: + case AV_RECEIVER_INTERFACE_SET_SPEAKERB_RESPONSE: + case AV_RECEIVER_INTERFACE_SEND_DIRECT_CMD_RESPONSE: + case AV_RECEIVER_INTERFACE_SET_SPEAKERS_RESPONSE: + case AV_RECEIVER_INTERFACE_SET_SPEAKERA_RESPONSE: + default: + { + qDebug("Received invalid msg from Sprinkler Interface"); + break; + } + } + + return 0; + +} diff --git a/Sources/AvReceiver/AvReceiverInterface.h b/Sources/AvReceiver/AvReceiverInterface.h new file mode 100644 index 0000000..637e656 --- /dev/null +++ b/Sources/AvReceiver/AvReceiverInterface.h @@ -0,0 +1,19 @@ +#ifndef AVRECEIVERINTERFACE_H +#define AVRECEIVERINTERFACE_H + +#include "NetworkDevice.h" +class CAVReceiverDevice; + +class CAvReceiverInterface: public QObject, public CNetworkDevice +{ + Q_OBJECT + +public: + CAvReceiverInterface(int Address, CAbstractNetworkCommIF *NetworkInterface, CAVReceiverDevice *DevicePtr ); + virtual int NewDeviceFrameReceived(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data); + +private: + CAVReceiverDevice *mAvReceiverDevice; +}; + +#endif // AVRECEIVERINTERFACE_H diff --git a/Sources/Chalet/ChaletLoraDevice.cpp b/Sources/Chalet/ChaletLoraDevice.cpp new file mode 100644 index 0000000..f566eb4 --- /dev/null +++ b/Sources/Chalet/ChaletLoraDevice.cpp @@ -0,0 +1,84 @@ +#include "ChaletLoraDevice.h" +#include +#include + +CChaletLoraDevice::CChaletLoraDevice() +{ + mMyLoraAddress = 5; + mMyLoraChannel = 4; + + QByteArray Test; + Test.resize(4); + Test[0] = 0xDE; + Test[1] = 0xAD; + Test[2] = 0xBE; + Test[3] = 0xEF; + + GetLoraFrame(4,4,Test); + + mLoraStatusRefreshTimer = new QTimer; + mLoraStatusRefreshTimer->setInterval(1000); + mLoraStatusRefreshTimer->setSingleShot(false); + connect(mLoraStatusRefreshTimer,SIGNAL(timeout()),this,SLOT(LoraStatusRefreshTimerExpired())); + + mLoraStatusRefreshTimer->start(); + +} + +CChaletLoraDevice::~CChaletLoraDevice() +{ + mLoraStatusRefreshTimer->stop(); + delete mLoraStatusRefreshTimer; +} + +int CChaletLoraDevice::Init() +{ + QList PortsList = QSerialPortInfo::availablePorts(); + + for(int i = 0; i < PortsList.size(); i++) + { + qDebug("Port found: %s - %s",qPrintable(PortsList.at(i).portName()),qPrintable(PortsList.at(i).description())); + + } + + mLoraModuleSerialPort.setPortName("COM3"); + mLoraModuleSerialPort.setBaudRate(QSerialPort::Baud9600); + mLoraModuleSerialPort.setDataBits(QSerialPort::Data8); + mLoraModuleSerialPort.setParity(QSerialPort::NoParity); + mLoraModuleSerialPort.setFlowControl(QSerialPort::NoFlowControl); + if(mLoraModuleSerialPort.open(QIODevice::ReadWrite) == false) + { + qDebug("Could not open Chalet Lora serial port"); + return RET_ERROR; + } + + QByteArray Test; + Test.resize(5); + Test[0] = 0xDE; + Test[1] = 0xAD; + Test[2] = 0xBE; + Test[3] = 0xEF; + Test[4] = '\r'; + + GetLoraFrame(4,4,Test); + + mLoraModuleSerialPort.write(GetLoraFrame(4,4,Test)); + + return RET_OK; +} + +void CChaletLoraDevice::LoraStatusRefreshTimerExpired() +{ + QByteArray Test; + Test.resize(4); + Test[0] = 0xBA; + Test[1] = 0xAD; + Test[2] = 0xCA; + Test[3] = 0xFE; +// Test[4] = '\r'; + + GetLoraFrame(4,4,Test); + + mLoraModuleSerialPort.write(GetLoraFrame(4,4,Test)); + return; +} diff --git a/Sources/Chalet/ChaletLoraDevice.h b/Sources/Chalet/ChaletLoraDevice.h new file mode 100644 index 0000000..f70bcb1 --- /dev/null +++ b/Sources/Chalet/ChaletLoraDevice.h @@ -0,0 +1,27 @@ +#ifndef CCHALETLORADEVICE_H +#define CCHALETLORADEVICE_H + +#include "GlobalDefine.h" +#include "LoraDevice.h" +#include +#include + + +class CChaletLoraDevice : public QObject, public CLoraDevice +{ + Q_OBJECT +public: + CChaletLoraDevice(); + ~CChaletLoraDevice(); + int Init(); + QTimer *mLoraStatusRefreshTimer; + + +private: + QSerialPort mLoraModuleSerialPort; + +public slots: + void LoraStatusRefreshTimerExpired(); +}; + +#endif // CCHALETLORADEVICE_H diff --git a/Sources/Chalet/LoraDevice.cpp b/Sources/Chalet/LoraDevice.cpp new file mode 100644 index 0000000..db086f7 --- /dev/null +++ b/Sources/Chalet/LoraDevice.cpp @@ -0,0 +1,25 @@ +#include "LoraDevice.h" + +CLoraDevice::CLoraDevice() +{ + +} + +QByteArray CLoraDevice::GetLoraFrame(unsigned short DestAddress, unsigned char DestChannel, QByteArray Payload) +{ + QByteArray OutputFrame; + OutputFrame.clear(); + + //E32 modules frame is [Address_MSB][Address_LSB][Channel][Payload] + + + + char AddressByte = (char)((DestAddress >> 8) & 0x00FF); + OutputFrame.append(AddressByte); + AddressByte = (char)(DestAddress & 0x00FF); + OutputFrame.append(AddressByte); + OutputFrame.append(DestChannel); + OutputFrame.append(Payload); + + return OutputFrame; +} diff --git a/Sources/Chalet/LoraDevice.h b/Sources/Chalet/LoraDevice.h new file mode 100644 index 0000000..ba60f58 --- /dev/null +++ b/Sources/Chalet/LoraDevice.h @@ -0,0 +1,16 @@ +#ifndef CLORADEVICE_H +#define CLORADEVICE_H +#include + +class CLoraDevice +{ +public: + CLoraDevice(); + + unsigned short mMyLoraAddress; + unsigned char mMyLoraChannel; + + QByteArray GetLoraFrame(unsigned short DestAddress,unsigned char DestChannel,QByteArray Payload); +}; + +#endif // CLORADEVICE_H diff --git a/Sources/EthernetNetworkServer.cpp b/Sources/EthernetNetworkServer.cpp index 34fd9ab..861f93c 100644 --- a/Sources/EthernetNetworkServer.cpp +++ b/Sources/EthernetNetworkServer.cpp @@ -166,6 +166,20 @@ void CEthernetNetworkServer::DeviceSocketDataAvail() } break; } + case ID_AVRECEIVER_INTERFACE: + { + if(mDevicesMgrHandle->CreateNewAvReceiverInterface(DeviceAddress,(CAbstractNetworkCommIF*)NetworkIF) == RET_OK) + { + Result = RES_CREATION_SUCCESS; + qDebug("Created new AV Receiver Interface"); + } + else + { + Result = RES_CREATION_FAILED; + qDebug("Could not create AV Receiver Interface in ethernet server"); + } + break; + } default: { Result = RES_CREATION_UNKNOWN_DEVICE; diff --git a/Sources/MasterCtrl.cpp b/Sources/MasterCtrl.cpp index e1caa4e..feb2dd1 100644 --- a/Sources/MasterCtrl.cpp +++ b/Sources/MasterCtrl.cpp @@ -9,12 +9,14 @@ CMasterCtrl::CMasterCtrl() { qDebug("Creation..."); // mDeadBoltDevice = new CDeadboltDevice(1); - mAVReceiverDevice = new CAVReceiverDevice; + mAVReceiverDevice = new CAVReceiverDevice(); mVoipMsSMSClient = new CVoipMsSMSClient; mSystemTrayManager = new CSystemTrayManager; mSystemTrayManager->mProgramHandle = this; mSettingsWindow = new CSettingsWindow(); mSettingsWindow->mProgramHandle = this; + mChaletLora = new CChaletLoraDevice; + mEthernetNetworkServer = new CEthernetNetworkServer; mNetworkDevicesManager = new CNetworkDevicesMgr; @@ -26,9 +28,6 @@ CMasterCtrl::CMasterCtrl() CMasterCtrl::~CMasterCtrl() { - mAVReceiverDevice->DisconnectReceiver(); - -// delete mDeadBoltDevice; delete mAVReceiverDevice; delete mVoipMsSMSClient; delete mSystemTrayManager; @@ -37,6 +36,7 @@ CMasterCtrl::~CMasterCtrl() delete mEthernetNetworkServer; delete mContactsRepository; delete mSprinklerManager; + delete mChaletLora; // delete mMasterCtrlSettings; } @@ -61,6 +61,8 @@ void CMasterCtrl::Start() mNetworkDevicesManager->mContactRepositoryHandle = mContactsRepository; mNetworkDevicesManager->mProgramHandle = this; mNetworkDevicesManager->mSprinklerMgrHandle = mSprinklerManager; + mNetworkDevicesManager->mAvReceiverDevice = mAVReceiverDevice; + mEthernetNetworkServer->mDevicesMgrHandle = mNetworkDevicesManager; mEthernetNetworkServer->mProgramHandle = this; @@ -71,7 +73,6 @@ void CMasterCtrl::Start() connect(mVoipMsSMSClient,SIGNAL(DIDSFetched(QStringList)),mSettingsWindow,SLOT(DIDsListFetched(QStringList))); - mAVReceiverDevice->ConnectToReceiver(); mSettingsManager.LoadSettings(&mMasterCtrlSettings); mSettingsWindow->SetSettingsData(&mMasterCtrlSettings); @@ -81,6 +82,11 @@ void CMasterCtrl::Start() mNetworkDevicesManager->InitNetworkDevices(); mEthernetNetworkServer->StartServer(2182); + mAVReceiverDevice->Start(); + + + mChaletLora->Init(); + // mAppWidget.show(); diff --git a/Sources/MasterCtrl.h b/Sources/MasterCtrl.h index 90174d7..d2d552f 100644 --- a/Sources/MasterCtrl.h +++ b/Sources/MasterCtrl.h @@ -12,6 +12,7 @@ #include "EthernetNetworkServer.h" #include "ContactRepository.h" #include "SprinklerMgr.h" +#include "ChaletLoraDevice.h" //#include "AppIconWidget.h" class CMasterCtrl : public QObject @@ -24,6 +25,7 @@ public: void Start(void); // CDeadboltDevice *mDeadBoltDevice; CAVReceiverDevice *mAVReceiverDevice; + CVoipMsSMSClient *mVoipMsSMSClient; CSystemTrayManager *mSystemTrayManager; CSettingsWindow *mSettingsWindow; @@ -32,6 +34,7 @@ public: CEthernetNetworkServer *mEthernetNetworkServer; CContactRepository *mContactsRepository; CSprinklerMgr *mSprinklerManager; + CChaletLoraDevice *mChaletLora; // CAppIconWidget mAppWidget; diff --git a/Sources/NetworkDevicesMgr.cpp b/Sources/NetworkDevicesMgr.cpp index 2819059..a4ed4d0 100644 --- a/Sources/NetworkDevicesMgr.cpp +++ b/Sources/NetworkDevicesMgr.cpp @@ -6,11 +6,13 @@ + CNetworkDevicesMgr::CNetworkDevicesMgr() { mVoipMSInterfaceHandle = 0; mProgramHandle = 0; mSprinklerMgrHandle = 0; + mAvReceiverDevice = 0; } CNetworkDevicesMgr::~CNetworkDevicesMgr() @@ -77,6 +79,19 @@ int CNetworkDevicesMgr::CreateNewSprinklerInterface(int Address, CAbstractNetwor return RET_OK; } +int CNetworkDevicesMgr::CreateNewAvReceiverInterface(int Address, CAbstractNetworkCommIF *NetworkIF) +{ + if(mAvReceiverDevice == 0) + { + return RET_ERROR; + } + + CAvReceiverInterface *AvReceiverInterface = new CAvReceiverInterface(Address,NetworkIF,mAvReceiverDevice); + mNetworkDevicesList.append((CNetworkDevice*)AvReceiverInterface); + + return RET_OK; +} + void CNetworkDevicesMgr::EthernetNetworkDeviceDisconnected(CNetworkDevice *Device) { qDebug("Device disconnected. ID: %d, Address: %d",Device->GetDeviceID(),Device->GetDeviceAddress()); diff --git a/Sources/NetworkDevicesMgr.h b/Sources/NetworkDevicesMgr.h index 117f2d9..08bc6be 100644 --- a/Sources/NetworkDevicesMgr.h +++ b/Sources/NetworkDevicesMgr.h @@ -2,11 +2,11 @@ #define CNETWORKDEVICESMGR_H #include "DeadboltDevice.h" -#include "AVReceiverDevice.h" #include "SMSDevice.h" #include "SprinklerDevice.h" #include "SprinklerInterface.h" #include "AbstractNetworkInterface.h" +#include "AvReceiverInterface.h" #include "QList" #include @@ -14,6 +14,7 @@ class CVoipMsSMSClient; class CMasterCtrl; class CContactRepository; class CSprinklerMgr; +class CAVReceiverDevice; class CNetworkDevicesMgr: public QObject { @@ -28,12 +29,13 @@ public: int CreateNewSMSDevice(int Address,CAbstractNetworkCommIF *NetworkIF); int CreateNewSprinklerDevice(int Address, CAbstractNetworkCommIF *NetworkIF); int CreateNewSprinklerInterface(int Address, CAbstractNetworkCommIF *NetworkIF); - + int CreateNewAvReceiverInterface(int Address, CAbstractNetworkCommIF *NetworkIF); int FindDeviceByPtr(CNetworkDevice *Device); CNetworkDevice *GetDevice(int DeviceID, int Address); QList GetDevices(int DeviceID); + CAVReceiverDevice *mAvReceiverDevice; CVoipMsSMSClient *mVoipMSInterfaceHandle; CContactRepository *mContactRepositoryHandle; CMasterCtrl *mProgramHandle; diff --git a/Sources/ProtocolDefs.h b/Sources/ProtocolDefs.h index 7874b55..a11ed71 100644 --- a/Sources/ProtocolDefs.h +++ b/Sources/ProtocolDefs.h @@ -27,16 +27,20 @@ jean-francois.martel@polymtl.ca enum eFrameIndex { - FRAME_HEADER_INDEX, - FRAME_SENDER_ID_INDEX, + FRAME_HEADER_INDEX = 0, FRAME_SENDER_ADDRESS_INDEX, - FRAME_DEST_ID_INDEX, + FRAME_SENDER_DEVICE_ID_INDEX, + FRAME_DEST_DEVICE_ID_INDEX, FRAME_DEST_ADDRESS_INDEX, FRAME_FLAGS_INDEX, FRAME_COMMAND_INDEX, FRAME_SIZE1_INDEX, FRAME_SIZE2_INDEX, - FRAME_DATA_INDEX + FRAME_SIZE3_INDEX, + FRAME_SIZE4_INDEX, + FRAME_DATA_INDEX, + + FRAME_INDEX_NBR }; enum DEVICES_IDS @@ -47,12 +51,13 @@ enum DEVICES_IDS ID_AV_MUX, //Audio Video Multiplexer ID_IR_REMOTE, //Infra red transmitter ID_DEADBOLT_DEVICE, - ID_RECEIVER_AMP, + ID_AV_RECEIVER, ID_SMS_CLIENT, ID_ETHERNET_VIRTUAL, ID_SPRINKLER_DEVICE, ID_SPRINKLER_INTERFACE, ID_DEADBOLT_INTERFACE, + ID_AVRECEIVER_INTERFACE, ID_NB_DEVICE_ID }; @@ -221,4 +226,24 @@ enum ETHERNET_NETWORK_VIRTUAL_CMDS }; +enum AV_RECEIVER_INTERFACE_CMDS +{ + AV_RECEIVER_INTERFACE_ACK = 1, + AV_RECEIVER_INTERFACE_GENERAL_STATUS_REQUEST, + AV_RECEIVER_INTERFACE_GENERAL_STATUS_RESPONSE, + AV_RECEIVER_INTERFACE_SET_MAIN_POWER_REQUEST, + AV_RECEIVER_INTERFACE_SET_MAIN_POWER_RESPONSE, + AV_RECEIVER_INTERFACE_SET_SPEAKERB_REQUEST, + AV_RECEIVER_INTERFACE_SET_SPEAKERB_RESPONSE, + AV_RECEIVER_INTERFACE_SET_SPEAKERA_REQUEST, + AV_RECEIVER_INTERFACE_SET_SPEAKERA_RESPONSE, + AV_RECEIVER_INTERFACE_SET_SPEAKERS_REQUEST, + AV_RECEIVER_INTERFACE_SET_SPEAKERS_RESPONSE, + AV_RECEIVER_INTERFACE_SEND_DIRECT_CMD_REQUEST, + AV_RECEIVER_INTERFACE_SEND_DIRECT_CMD_RESPONSE, + + + MAX_AV_RECEIVER_INTERFACE_CMD +}; + #endif diff --git a/Sources/VoipSMS/VoipMsSMSClient.cpp b/Sources/VoipSMS/VoipMsSMSClient.cpp index 3196164..6c7d01c 100644 --- a/Sources/VoipSMS/VoipMsSMSClient.cpp +++ b/Sources/VoipSMS/VoipMsSMSClient.cpp @@ -12,6 +12,7 @@ CVoipMsSMSClient::CVoipMsSMSClient() { mVOIPMSSocket = new QNetworkAccessManager(); connect(mVOIPMSSocket,SIGNAL(finished(QNetworkReply*)),this,SLOT(VoipServerReplyFinished(QNetworkReply*))); + connect(mVOIPMSSocket,SIGNAL(sslErrors(QNetworkReply*,QList)),this,SLOT(sslErrors(QNetworkReply*,QList))); mVOIPMsNotificationServer = new QTcpServer; connect(mVOIPMsNotificationServer,SIGNAL(newConnection()),this,SLOT(VoipNotificationServerConnected())); @@ -66,7 +67,7 @@ int CVoipMsSMSClient::SendSMSDownloadRequest(QDate StartDate, QDate EndDate) // qDebug() << "Sending request for dates from: " << StartDate.toString("yyyy-MM-dd") << " to: " << EndDate.toString("yyyy-MM-dd"); - // Url = "https://www.voip.ms/api/v1/rest.php?api_username=jean-francois.martel@polymtl.ca&api_password=Pentium2&method=getSMS&from=2015-11-01&to=2015-11-11&did=5143606463&limit=50"; +// Url = "https://www.voip.ms/api/v1/rest.php?api_username=jean-francois@jfmartel.ca&api_password=Pentium2&method=getSMS&from=2015-11-01&to=2015-11-11&did=5143606463&limit=50"; StopSMSCheckTimer(); @@ -79,7 +80,7 @@ int CVoipMsSMSClient::SendSMSDownloadRequest(QDate StartDate, QDate EndDate) << "did=" << mVOIPMsSettings.mDefaultDID << "&" << "limit=" << VOIP_MS_SMS_MAX_COUNT; -// qDebug() << "Cmd: " << Url; + //qDebug() << "Cmd: " << Url; mVOIPMSSocket->get(QNetworkRequest(Url)); mCurStartDate = EndDate; @@ -175,8 +176,23 @@ unsigned int CVoipMsSMSClient::GetDidFromUserAccount(const QString username, con return RET_OK; } +void CVoipMsSMSClient::sslErrors(QNetworkReply *reply, QList errors) +{ + qDebug("Ssl errors..."); + reply->ignoreSslErrors(); +} + void CVoipMsSMSClient::VoipServerReplyFinished(QNetworkReply *NetworkReply) { + if(NetworkReply->isFinished() == false) + return; + + if(NetworkReply->error() != QNetworkReply::NoError) + { + qDebug("Network error... %d", NetworkReply->error()); + return; + } + QByteArray Reply = NetworkReply->readAll(); NetworkReply->deleteLater(); @@ -273,7 +289,7 @@ unsigned int CVoipMsSMSClient::SMSReceived(QJsonArray *SMSArray) } NBMsgReceived = NewMessages.size(); - // qDebug() << "Received " << NBMsgReceived << "messages"; + // qDebug() << "Received " << NBMsgReceived << "messages"; if(mSMSMessagesList.size() >0 && NewMessages.size() > 0) @@ -396,7 +412,7 @@ unsigned int CVoipMsSMSClient::SMSReceived(QJsonArray *SMSArray) if(NewMessages.size() != 0) { mSMSMessagesList.append(NewMessages); - qDebug("Added %d new msgs. mCurStartDate:%s", NewMessages.size(),mCurStartDate.toString("yyyy-MM-dd").toUtf8().data()); +// qDebug("Added %d new msgs. mCurStartDate:%s", NewMessages.size(),mCurStartDate.toString("yyyy-MM-dd").toUtf8().data()); } //Restart at the last day received... mCurStartDate = mSMSMessagesList.last().mDateTime.date(); @@ -410,7 +426,7 @@ unsigned int CVoipMsSMSClient::SMSReceived(QJsonArray *SMSArray) qDebug("Requesting data for last block of span"); mSMSDownloadState = VOIPMS_SMS_DOWNLOAD_LAST_BLOCK_MSGS_STATE; } - qDebug("Continue receiving from %s to %s ...",mCurStartDate.toString("yyyy-MM-dd").toUtf8().data(),EarlierDate.toString("yyyy-MM-dd").toUtf8().data()); +// qDebug("Continue receiving from %s to %s ...",mCurStartDate.toString("yyyy-MM-dd").toUtf8().data(),EarlierDate.toString("yyyy-MM-dd").toUtf8().data()); SendSMSDownloadRequest(EarlierDate,mCurStartDate); break; } @@ -419,13 +435,13 @@ unsigned int CVoipMsSMSClient::SMSReceived(QJsonArray *SMSArray) if(NewMessages.size() != 0) { mSMSMessagesList.append(NewMessages); - qDebug("Added %d new msgs. mCurStartDate:%s", NewMessages.size(),mCurStartDate.toString("yyyy-MM-dd").toUtf8().data()); +// qDebug("Added %d new msgs. mCurStartDate:%s", NewMessages.size(),mCurStartDate.toString("yyyy-MM-dd").toUtf8().data()); } if(NBMsgReceived == VOIP_MS_SMS_MAX_COUNT) { mCurStartDate = mSMSMessagesList.last().mDateTime.date(); - qDebug("Continue receiving from %s to %s ...",mVOIPMsSettings.mStartDate.toString("yyyy-MM-dd").toUtf8().data(),mVOIPMsSettings.mStartDate.toString("yyyy-MM-dd").toUtf8().data()); +// qDebug("Continue receiving from %s to %s ...",mVOIPMsSettings.mStartDate.toString("yyyy-MM-dd").toUtf8().data(),mVOIPMsSettings.mStartDate.toString("yyyy-MM-dd").toUtf8().data()); SendSMSDownloadRequest(mCurStartDate,mVOIPMsSettings.mStartDate);//download for the first day of the span only... } else @@ -443,7 +459,7 @@ unsigned int CVoipMsSMSClient::SMSReceived(QJsonArray *SMSArray) mSMSDownloadState = VOIPMS_SMS_GET_NEW_MSGS_STATE; StartSMSCheckTimer(); - qDebug("Timer started in VOIPMS_SMS_DOWNLOAD_LAST_DAY_MSGS_STATE"); + // qDebug("Timer started in VOIPMS_SMS_DOWNLOAD_LAST_DAY_MSGS_STATE"); } break; } @@ -456,11 +472,11 @@ unsigned int CVoipMsSMSClient::SMSReceived(QJsonArray *SMSArray) { mSMSMessagesList.prepend(NewMessages[i-1]); } - qDebug("Added %d new msgs. mCurStartDate:%s", NewMessages.size(),mCurStartDate.toString("yyyy-MM-dd").toUtf8().data()); +// qDebug("Added %d new msgs. mCurStartDate:%s", NewMessages.size(),mCurStartDate.toString("yyyy-MM-dd").toUtf8().data()); } StartSMSCheckTimer(); - qDebug("Timer started in VOIPMS_SMS_GET_NEW_MSGS_STATE"); +// qDebug("Timer started in VOIPMS_SMS_GET_NEW_MSGS_STATE"); if(NewMessages.size() > 0) { diff --git a/Sources/VoipSMS/VoipMsSMSClient.h b/Sources/VoipSMS/VoipMsSMSClient.h index 1303ab2..ee107be 100644 --- a/Sources/VoipSMS/VoipMsSMSClient.h +++ b/Sources/VoipSMS/VoipMsSMSClient.h @@ -100,6 +100,7 @@ public slots: void VoipNotificationServerConnected(); void VoipNotificationServerDataAvail(); void CheckNewSMSTimerExpired(); + void sslErrors(QNetworkReply *, QList); }; diff --git a/Sources/qextserialport/posix_qextserialport.cpp b/Sources/qextserialport/posix_qextserialport.cpp deleted file mode 100644 index c7f923c..0000000 --- a/Sources/qextserialport/posix_qextserialport.cpp +++ /dev/null @@ -1,959 +0,0 @@ - - -#include -#include -#include "qextserialport.h" -#include -#include - -void QextSerialPort::platformSpecificInit() -{ - fd = 0; - readNotifier = 0; -} - -/*! -Standard destructor. -*/ -void QextSerialPort::platformSpecificDestruct() -{} - -/*! -Sets the baud rate of the serial port. Note that not all rates are applicable on -all platforms. The following table shows translations of the various baud rate -constants on Windows(including NT/2000) and POSIX platforms. Speeds marked with an * -are speeds that are usable on both Windows and POSIX. - -\note -BAUD76800 may not be supported on all POSIX systems. SGI/IRIX systems do not support -BAUD1800. - -\verbatim - - RATE Windows Speed POSIX Speed - ----------- ------------- ----------- - BAUD50 110 50 - BAUD75 110 75 - *BAUD110 110 110 - BAUD134 110 134.5 - BAUD150 110 150 - BAUD200 110 200 - *BAUD300 300 300 - *BAUD600 600 600 - *BAUD1200 1200 1200 - BAUD1800 1200 1800 - *BAUD2400 2400 2400 - *BAUD4800 4800 4800 - *BAUD9600 9600 9600 - BAUD14400 14400 9600 - *BAUD19200 19200 19200 - *BAUD38400 38400 38400 - BAUD56000 56000 38400 - *BAUD57600 57600 57600 - BAUD76800 57600 76800 - *BAUD115200 115200 115200 - BAUD128000 128000 115200 - BAUD256000 256000 115200 -\endverbatim -*/ -void QextSerialPort::setBaudRate(BaudRateType baudRate) -{ - QMutexLocker lock(mutex); - if (Settings.BaudRate!=baudRate) { - switch (baudRate) { - case BAUD14400: - Settings.BaudRate=BAUD9600; - break; - - case BAUD56000: - Settings.BaudRate=BAUD38400; - break; - - case BAUD76800: - -#ifndef B76800 - Settings.BaudRate=BAUD57600; -#else - Settings.BaudRate=baudRate; -#endif - break; - - case BAUD128000: - case BAUD256000: - Settings.BaudRate=BAUD115200; - break; - - default: - Settings.BaudRate=baudRate; - break; - } - } - if (isOpen()) { - switch (baudRate) { - - /*50 baud*/ - case BAUD50: - TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 50 baud operation."); -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B50; -#else - cfsetispeed(&Posix_CommConfig, B50); - cfsetospeed(&Posix_CommConfig, B50); -#endif - break; - - /*75 baud*/ - case BAUD75: - TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 75 baud operation."); -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B75; -#else - cfsetispeed(&Posix_CommConfig, B75); - cfsetospeed(&Posix_CommConfig, B75); -#endif - break; - - /*110 baud*/ - case BAUD110: -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B110; -#else - cfsetispeed(&Posix_CommConfig, B110); - cfsetospeed(&Posix_CommConfig, B110); -#endif - break; - - /*134.5 baud*/ - case BAUD134: - TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 134.5 baud operation."); -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B134; -#else - cfsetispeed(&Posix_CommConfig, B134); - cfsetospeed(&Posix_CommConfig, B134); -#endif - break; - - /*150 baud*/ - case BAUD150: - TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 150 baud operation."); -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B150; -#else - cfsetispeed(&Posix_CommConfig, B150); - cfsetospeed(&Posix_CommConfig, B150); -#endif - break; - - /*200 baud*/ - case BAUD200: - TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 200 baud operation."); -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B200; -#else - cfsetispeed(&Posix_CommConfig, B200); - cfsetospeed(&Posix_CommConfig, B200); -#endif - break; - - /*300 baud*/ - case BAUD300: -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B300; -#else - cfsetispeed(&Posix_CommConfig, B300); - cfsetospeed(&Posix_CommConfig, B300); -#endif - break; - - /*600 baud*/ - case BAUD600: -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B600; -#else - cfsetispeed(&Posix_CommConfig, B600); - cfsetospeed(&Posix_CommConfig, B600); -#endif - break; - - /*1200 baud*/ - case BAUD1200: -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B1200; -#else - cfsetispeed(&Posix_CommConfig, B1200); - cfsetospeed(&Posix_CommConfig, B1200); -#endif - break; - - /*1800 baud*/ - case BAUD1800: - TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows and IRIX do not support 1800 baud operation."); -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B1800; -#else - cfsetispeed(&Posix_CommConfig, B1800); - cfsetospeed(&Posix_CommConfig, B1800); -#endif - break; - - /*2400 baud*/ - case BAUD2400: -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B2400; -#else - cfsetispeed(&Posix_CommConfig, B2400); - cfsetospeed(&Posix_CommConfig, B2400); -#endif - break; - - /*4800 baud*/ - case BAUD4800: -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B4800; -#else - cfsetispeed(&Posix_CommConfig, B4800); - cfsetospeed(&Posix_CommConfig, B4800); -#endif - break; - - /*9600 baud*/ - case BAUD9600: -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B9600; -#else - cfsetispeed(&Posix_CommConfig, B9600); - cfsetospeed(&Posix_CommConfig, B9600); -#endif - break; - - /*14400 baud*/ - case BAUD14400: - TTY_WARNING("QextSerialPort: POSIX does not support 14400 baud operation. Switching to 9600 baud."); -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B9600; -#else - cfsetispeed(&Posix_CommConfig, B9600); - cfsetospeed(&Posix_CommConfig, B9600); -#endif - break; - - /*19200 baud*/ - case BAUD19200: -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B19200; -#else - cfsetispeed(&Posix_CommConfig, B19200); - cfsetospeed(&Posix_CommConfig, B19200); -#endif - break; - - /*38400 baud*/ - case BAUD38400: -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B38400; -#else - cfsetispeed(&Posix_CommConfig, B38400); - cfsetospeed(&Posix_CommConfig, B38400); -#endif - break; - - /*56000 baud*/ - case BAUD56000: - TTY_WARNING("QextSerialPort: POSIX does not support 56000 baud operation. Switching to 38400 baud."); -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B38400; -#else - cfsetispeed(&Posix_CommConfig, B38400); - cfsetospeed(&Posix_CommConfig, B38400); -#endif - break; - - /*57600 baud*/ - case BAUD57600: -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B57600; -#else - cfsetispeed(&Posix_CommConfig, B57600); - cfsetospeed(&Posix_CommConfig, B57600); -#endif - break; - - /*76800 baud*/ - case BAUD76800: - TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows and some POSIX systems do not support 76800 baud operation."); -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - -#ifdef B76800 - Posix_CommConfig.c_cflag|=B76800; -#else - TTY_WARNING("QextSerialPort: QextSerialPort was compiled without 76800 baud support. Switching to 57600 baud."); - Posix_CommConfig.c_cflag|=B57600; -#endif //B76800 -#else //CBAUD -#ifdef B76800 - cfsetispeed(&Posix_CommConfig, B76800); - cfsetospeed(&Posix_CommConfig, B76800); -#else - TTY_WARNING("QextSerialPort: QextSerialPort was compiled without 76800 baud support. Switching to 57600 baud."); - cfsetispeed(&Posix_CommConfig, B57600); - cfsetospeed(&Posix_CommConfig, B57600); -#endif //B76800 -#endif //CBAUD - break; - - /*115200 baud*/ - case BAUD115200: -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B115200; -#else - cfsetispeed(&Posix_CommConfig, B115200); - cfsetospeed(&Posix_CommConfig, B115200); -#endif - break; - - /*128000 baud*/ - case BAUD128000: - TTY_WARNING("QextSerialPort: POSIX does not support 128000 baud operation. Switching to 115200 baud."); -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B115200; -#else - cfsetispeed(&Posix_CommConfig, B115200); - cfsetospeed(&Posix_CommConfig, B115200); -#endif - break; - - /*256000 baud*/ - case BAUD256000: - TTY_WARNING("QextSerialPort: POSIX does not support 256000 baud operation. Switching to 115200 baud."); -#ifdef CBAUD - Posix_CommConfig.c_cflag&=(~CBAUD); - Posix_CommConfig.c_cflag|=B115200; -#else - cfsetispeed(&Posix_CommConfig, B115200); - cfsetospeed(&Posix_CommConfig, B115200); -#endif - break; - } - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - } -} - -/*! -Sets the number of data bits used by the serial port. Possible values of dataBits are: -\verbatim - DATA_5 5 data bits - DATA_6 6 data bits - DATA_7 7 data bits - DATA_8 8 data bits -\endverbatim - -\note -This function is subject to the following restrictions: -\par - 5 data bits cannot be used with 2 stop bits. -\par - 8 data bits cannot be used with space parity on POSIX systems. -*/ -void QextSerialPort::setDataBits(DataBitsType dataBits) -{ - QMutexLocker lock(mutex); - if (Settings.DataBits!=dataBits) { - if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) || - (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5) || - (Settings.Parity==PAR_SPACE && dataBits==DATA_8)) { - } - else { - Settings.DataBits=dataBits; - } - } - if (isOpen()) { - switch(dataBits) { - - /*5 data bits*/ - case DATA_5: - if (Settings.StopBits==STOP_2) { - TTY_WARNING("QextSerialPort: 5 Data bits cannot be used with 2 stop bits."); - } - else { - Settings.DataBits=dataBits; - Posix_CommConfig.c_cflag&=(~CSIZE); - Posix_CommConfig.c_cflag|=CS5; - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - } - break; - - /*6 data bits*/ - case DATA_6: - if (Settings.StopBits==STOP_1_5) { - TTY_WARNING("QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits."); - } - else { - Settings.DataBits=dataBits; - Posix_CommConfig.c_cflag&=(~CSIZE); - Posix_CommConfig.c_cflag|=CS6; - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - } - break; - - /*7 data bits*/ - case DATA_7: - if (Settings.StopBits==STOP_1_5) { - TTY_WARNING("QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits."); - } - else { - Settings.DataBits=dataBits; - Posix_CommConfig.c_cflag&=(~CSIZE); - Posix_CommConfig.c_cflag|=CS7; - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - } - break; - - /*8 data bits*/ - case DATA_8: - if (Settings.StopBits==STOP_1_5) { - TTY_WARNING("QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits."); - } - else { - Settings.DataBits=dataBits; - Posix_CommConfig.c_cflag&=(~CSIZE); - Posix_CommConfig.c_cflag|=CS8; - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - } - break; - } - } -} - -/*! -Sets the parity associated with the serial port. The possible values of parity are: -\verbatim - PAR_SPACE Space Parity - PAR_MARK Mark Parity - PAR_NONE No Parity - PAR_EVEN Even Parity - PAR_ODD Odd Parity -\endverbatim - -\note -This function is subject to the following limitations: -\par -POSIX systems do not support mark parity. -\par -POSIX systems support space parity only if tricked into doing so, and only with - fewer than 8 data bits. Use space parity very carefully with POSIX systems. -*/ -void QextSerialPort::setParity(ParityType parity) -{ - QMutexLocker lock(mutex); - if (Settings.Parity!=parity) { - if (parity==PAR_MARK || (parity==PAR_SPACE && Settings.DataBits==DATA_8)) { - } - else { - Settings.Parity=parity; - } - } - if (isOpen()) { - switch (parity) { - - /*space parity*/ - case PAR_SPACE: - if (Settings.DataBits==DATA_8) { - TTY_PORTABILITY_WARNING("QextSerialPort: Space parity is only supported in POSIX with 7 or fewer data bits"); - } - else { - - /*space parity not directly supported - add an extra data bit to simulate it*/ - Posix_CommConfig.c_cflag&=~(PARENB|CSIZE); - switch(Settings.DataBits) { - case DATA_5: - Settings.DataBits=DATA_6; - Posix_CommConfig.c_cflag|=CS6; - break; - - case DATA_6: - Settings.DataBits=DATA_7; - Posix_CommConfig.c_cflag|=CS7; - break; - - case DATA_7: - Settings.DataBits=DATA_8; - Posix_CommConfig.c_cflag|=CS8; - break; - - case DATA_8: - break; - } - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - } - break; - - /*mark parity - WINDOWS ONLY*/ - case PAR_MARK: - TTY_WARNING("QextSerialPort: Mark parity is not supported by POSIX."); - break; - - /*no parity*/ - case PAR_NONE: - Posix_CommConfig.c_cflag&=(~PARENB); - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - break; - - /*even parity*/ - case PAR_EVEN: - Posix_CommConfig.c_cflag&=(~PARODD); - Posix_CommConfig.c_cflag|=PARENB; - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - break; - - /*odd parity*/ - case PAR_ODD: - Posix_CommConfig.c_cflag|=(PARENB|PARODD); - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - break; - } - } -} - -/*! -Sets the number of stop bits used by the serial port. Possible values of stopBits are: -\verbatim - STOP_1 1 stop bit - STOP_1_5 1.5 stop bits - STOP_2 2 stop bits -\endverbatim -\note -This function is subject to the following restrictions: -\par - 2 stop bits cannot be used with 5 data bits. -\par - POSIX does not support 1.5 stop bits. - -*/ -void QextSerialPort::setStopBits(StopBitsType stopBits) -{ - QMutexLocker lock(mutex); - if (Settings.StopBits!=stopBits) { - if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) || stopBits==STOP_1_5) {} - else { - Settings.StopBits=stopBits; - } - } - if (isOpen()) { - switch (stopBits) { - - /*one stop bit*/ - case STOP_1: - Settings.StopBits=stopBits; - Posix_CommConfig.c_cflag&=(~CSTOPB); - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - break; - - /*1.5 stop bits*/ - case STOP_1_5: - TTY_WARNING("QextSerialPort: 1.5 stop bit operation is not supported by POSIX."); - break; - - /*two stop bits*/ - case STOP_2: - if (Settings.DataBits==DATA_5) { - TTY_WARNING("QextSerialPort: 2 stop bits cannot be used with 5 data bits"); - } - else { - Settings.StopBits=stopBits; - Posix_CommConfig.c_cflag|=CSTOPB; - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - } - break; - } - } -} - -/*! -Sets the flow control used by the port. Possible values of flow are: -\verbatim - FLOW_OFF No flow control - FLOW_HARDWARE Hardware (RTS/CTS) flow control - FLOW_XONXOFF Software (XON/XOFF) flow control -\endverbatim -\note -FLOW_HARDWARE may not be supported on all versions of UNIX. In cases where it is -unsupported, FLOW_HARDWARE is the same as FLOW_OFF. - -*/ -void QextSerialPort::setFlowControl(FlowType flow) -{ - QMutexLocker lock(mutex); - if (Settings.FlowControl!=flow) { - Settings.FlowControl=flow; - } - if (isOpen()) { - switch(flow) { - - /*no flow control*/ - case FLOW_OFF: - Posix_CommConfig.c_cflag&=(~CRTSCTS); - Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY)); - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - break; - - /*software (XON/XOFF) flow control*/ - case FLOW_XONXOFF: - Posix_CommConfig.c_cflag&=(~CRTSCTS); - Posix_CommConfig.c_iflag|=(IXON|IXOFF|IXANY); - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - break; - - case FLOW_HARDWARE: - Posix_CommConfig.c_cflag|=CRTSCTS; - Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY)); - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - break; - } - } -} - -/*! -Sets the read and write timeouts for the port to millisec milliseconds. -Note that this is a per-character timeout, i.e. the port will wait this long for each -individual character, not for the whole read operation. This timeout also applies to the -bytesWaiting() function. - -\note -POSIX does not support millisecond-level control for I/O timeout values. Any -timeout set using this function will be set to the next lowest tenth of a second for -the purposes of detecting read or write timeouts. For example a timeout of 550 milliseconds -will be seen by the class as a timeout of 500 milliseconds for the purposes of reading and -writing the port. However millisecond-level control is allowed by the select() system call, -so for example a 550-millisecond timeout will be seen as 550 milliseconds on POSIX systems for -the purpose of detecting available bytes in the read buffer. - -*/ -void QextSerialPort::setTimeout(long millisec) -{ - QMutexLocker lock(mutex); - Settings.Timeout_Millisec = millisec; - Posix_Copy_Timeout.tv_sec = millisec / 1000; - Posix_Copy_Timeout.tv_usec = millisec % 1000; - if (isOpen()) { - if (millisec == -1) - fcntl(fd, F_SETFL, O_NDELAY); - else - //O_SYNC should enable blocking ::write() - //however this seems not working on Linux 2.6.21 (works on OpenBSD 4.2) - fcntl(fd, F_SETFL, O_SYNC); - tcgetattr(fd, & Posix_CommConfig); - Posix_CommConfig.c_cc[VTIME] = millisec/100; - tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig); - } -} - -/*! -Opens the serial port associated to this class. -This function has no effect if the port associated with the class is already open. -The port is also configured to the current settings, as stored in the Settings structure. -*/ -bool QextSerialPort::open(OpenMode mode) -{ - QMutexLocker lock(mutex); - if (mode == QIODevice::NotOpen) - return isOpen(); - if (!isOpen()) { - qDebug() << "trying to open file" << port.toAscii(); - //note: linux 2.6.21 seems to ignore O_NDELAY flag - if ((fd = ::open(port.toAscii() ,O_RDWR | O_NOCTTY | O_NDELAY)) != -1) { - qDebug("file opened succesfully"); - - setOpenMode(mode); // Flag the port as opened - tcgetattr(fd, &old_termios); // Save the old termios - Posix_CommConfig = old_termios; // Make a working copy - cfmakeraw(&Posix_CommConfig); // Enable raw access - - /*set up other port settings*/ - Posix_CommConfig.c_cflag|=CREAD|CLOCAL; - Posix_CommConfig.c_lflag&=(~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); - Posix_CommConfig.c_iflag&=(~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY)); - Posix_CommConfig.c_oflag&=(~OPOST); - Posix_CommConfig.c_cc[VMIN]= 0; -#ifdef _POSIX_VDISABLE // Is a disable character available on this system? - // Some systems allow for per-device disable-characters, so get the - // proper value for the configured device - const long vdisable = fpathconf(fd, _PC_VDISABLE); - Posix_CommConfig.c_cc[VINTR] = vdisable; - Posix_CommConfig.c_cc[VQUIT] = vdisable; - Posix_CommConfig.c_cc[VSTART] = vdisable; - Posix_CommConfig.c_cc[VSTOP] = vdisable; - Posix_CommConfig.c_cc[VSUSP] = vdisable; -#endif //_POSIX_VDISABLE - setBaudRate(Settings.BaudRate); - setDataBits(Settings.DataBits); - setParity(Settings.Parity); - setStopBits(Settings.StopBits); - setFlowControl(Settings.FlowControl); - setTimeout(Settings.Timeout_Millisec); - tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); - - if (queryMode() == QextSerialPort::EventDriven) { - readNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this); - connect(readNotifier, SIGNAL(activated(int)), this, SIGNAL(readyRead())); - } - } else { - qDebug() << "could not open file:" << strerror(errno); - lastErr = E_FILE_NOT_FOUND; - } - } - return isOpen(); -} - -/*! -Closes a serial port. This function has no effect if the serial port associated with the class -is not currently open. -*/ -void QextSerialPort::close() -{ - QMutexLocker lock(mutex); - if( isOpen() ) - { - // Force a flush and then restore the original termios - flush(); - // Using both TCSAFLUSH and TCSANOW here discards any pending input - tcsetattr(fd, TCSAFLUSH | TCSANOW, &old_termios); // Restore termios - // Be a good QIODevice and call QIODevice::close() before POSIX close() - // so the aboutToClose() signal is emitted at the proper time - QIODevice::close(); // Flag the device as closed - // QIODevice::close() doesn't actually close the port, so do that here - ::close(fd); - if(readNotifier) { - delete readNotifier; - readNotifier = 0; - } - } -} - -/*! -Flushes all pending I/O to the serial port. This function has no effect if the serial port -associated with the class is not currently open. -*/ -void QextSerialPort::flush() -{ - QMutexLocker lock(mutex); - if (isOpen()) - tcflush(fd, TCIOFLUSH); -} - -/*! -This function will return the number of bytes waiting in the receive queue of the serial port. -It is included primarily to provide a complete QIODevice interface, and will not record errors -in the lastErr member (because it is const). This function is also not thread-safe - in -multithreading situations, use QextSerialPort::bytesWaiting() instead. -*/ -qint64 QextSerialPort::size() const -{ - int numBytes; - if (ioctl(fd, FIONREAD, &numBytes)<0) { - numBytes = 0; - } - return (qint64)numBytes; -} - -/*! -Returns the number of bytes waiting in the port's receive queue. This function will return 0 if -the port is not currently open, or -1 on error. -*/ -qint64 QextSerialPort::bytesAvailable() const -{ - QMutexLocker lock(mutex); - if (isOpen()) { - int bytesQueued; - if (ioctl(fd, FIONREAD, &bytesQueued) == -1) { - return (qint64)-1; - } - return bytesQueued + QIODevice::bytesAvailable(); - } - return 0; -} - -/*! -This function is included to implement the full QIODevice interface, and currently has no -purpose within this class. This function is meaningless on an unbuffered device and currently -only prints a warning message to that effect. -*/ -void QextSerialPort::ungetChar(char) -{ - /*meaningless on unbuffered sequential device - return error and print a warning*/ - TTY_WARNING("QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless"); -} - -/*! -Translates a system-specific error code to a QextSerialPort error code. Used internally. -*/ -void QextSerialPort::translateError(ulong error) -{ - switch (error) { - case EBADF: - case ENOTTY: - lastErr=E_INVALID_FD; - break; - - case EINTR: - lastErr=E_CAUGHT_NON_BLOCKED_SIGNAL; - break; - - case ENOMEM: - lastErr=E_NO_MEMORY; - break; - } -} - -/*! -Sets DTR line to the requested state (high by default). This function will have no effect if -the port associated with the class is not currently open. -*/ -void QextSerialPort::setDtr(bool set) -{ - QMutexLocker lock(mutex); - if (isOpen()) { - int status; - ioctl(fd, TIOCMGET, &status); - if (set) { - status|=TIOCM_DTR; - } - else { - status&=~TIOCM_DTR; - } - ioctl(fd, TIOCMSET, &status); - } -} - -/*! -Sets RTS line to the requested state (high by default). This function will have no effect if -the port associated with the class is not currently open. -*/ -void QextSerialPort::setRts(bool set) -{ - QMutexLocker lock(mutex); - if (isOpen()) { - int status; - ioctl(fd, TIOCMGET, &status); - if (set) { - status|=TIOCM_RTS; - } - else { - status&=~TIOCM_RTS; - } - ioctl(fd, TIOCMSET, &status); - } -} - -/*! -Returns the line status as stored by the port function. This function will retrieve the states -of the following lines: DCD, CTS, DSR, and RI. On POSIX systems, the following additional lines -can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD. The value returned is an unsigned -long with specific bits indicating which lines are high. The following constants should be used -to examine the states of individual lines: - -\verbatim -Mask Line ------- ---- -LS_CTS CTS -LS_DSR DSR -LS_DCD DCD -LS_RI RI -LS_RTS RTS (POSIX only) -LS_DTR DTR (POSIX only) -LS_ST Secondary TXD (POSIX only) -LS_SR Secondary RXD (POSIX only) -\endverbatim - -This function will return 0 if the port associated with the class is not currently open. -*/ -unsigned long QextSerialPort::lineStatus() -{ - unsigned long Status=0, Temp=0; - QMutexLocker lock(mutex); - if (isOpen()) { - ioctl(fd, TIOCMGET, &Temp); - if (Temp&TIOCM_CTS) { - Status|=LS_CTS; - } - if (Temp&TIOCM_DSR) { - Status|=LS_DSR; - } - if (Temp&TIOCM_RI) { - Status|=LS_RI; - } - if (Temp&TIOCM_CD) { - Status|=LS_DCD; - } - if (Temp&TIOCM_DTR) { - Status|=LS_DTR; - } - if (Temp&TIOCM_RTS) { - Status|=LS_RTS; - } - if (Temp&TIOCM_ST) { - Status|=LS_ST; - } - if (Temp&TIOCM_SR) { - Status|=LS_SR; - } - } - return Status; -} - -/*! -Reads a block of data from the serial port. This function will read at most maxSize bytes from -the serial port and place them in the buffer pointed to by data. Return value is the number of -bytes actually read, or -1 on error. - -\warning before calling this function ensure that serial port associated with this class -is currently open (use isOpen() function to check if port is open). -*/ -qint64 QextSerialPort::readData(char * data, qint64 maxSize) -{ - QMutexLocker lock(mutex); - int retVal = ::read(fd, data, maxSize); - if (retVal == -1) - lastErr = E_READ_FAILED; - - return retVal; -} - -/*! -Writes a block of data to the serial port. This function will write maxSize bytes -from the buffer pointed to by data to the serial port. Return value is the number -of bytes actually written, or -1 on error. - -\warning before calling this function ensure that serial port associated with this class -is currently open (use isOpen() function to check if port is open). -*/ -qint64 QextSerialPort::writeData(const char * data, qint64 maxSize) -{ - QMutexLocker lock(mutex); - int retVal = ::write(fd, data, maxSize); - if (retVal == -1) - lastErr = E_WRITE_FAILED; - - return (qint64)retVal; -} diff --git a/Sources/qextserialport/qextserialenumerator.h b/Sources/qextserialport/qextserialenumerator.h deleted file mode 100644 index 329648e..0000000 --- a/Sources/qextserialport/qextserialenumerator.h +++ /dev/null @@ -1,199 +0,0 @@ -/*! - * \file qextserialenumerator.h - * \author Michal Policht - * \see QextSerialEnumerator - */ - -#ifndef _QEXTSERIALENUMERATOR_H_ -#define _QEXTSERIALENUMERATOR_H_ - - -#include -#include -#include -#include "qextserialport_global.h" - -#ifdef Q_OS_WIN - #include - #include - #include -#endif /*Q_OS_WIN*/ - -#ifdef Q_OS_MAC - #include -#endif - -/*! - * Structure containing port information. - */ -struct QextPortInfo { - QString portName; ///< Port name. - QString physName; ///< Physical name. - QString friendName; ///< Friendly name. - QString enumName; ///< Enumerator name. - int vendorID; ///< Vendor ID. - int productID; ///< Product ID -}; - -#ifdef Q_OS_WIN -#ifdef QT_GUI_LIB -#include -class QextSerialEnumerator; - -class QextSerialRegistrationWidget : public QWidget -{ - Q_OBJECT - public: - QextSerialRegistrationWidget( QextSerialEnumerator* qese ) { - this->qese = qese; - } - ~QextSerialRegistrationWidget( ) { } - - protected: - QextSerialEnumerator* qese; - bool winEvent( MSG* message, long* result ); -}; -#endif // QT_GUI_LIB -#endif // Q_OS_WIN - -/*! - Provides list of ports available in the system. - - \section Usage - To poll the system for a list of connected devices, simply use getPorts(). Each - QextPortInfo structure will populated with information about the corresponding device. - - \b Example - \code - QList ports = QextSerialEnumerator::getPorts(); - foreach( QextPortInfo port, ports ) { - // inspect port... - } - \endcode - - To enable event-driven notification of device connection events, first call - setUpNotifications() and then connect to the deviceDiscovered() and deviceRemoved() - signals. Event-driven behavior is currently available only on Windows and OS X. - - \b Example - \code - QextSerialEnumerator* enumerator = new QextSerialEnumerator(); - connect(enumerator, SIGNAL(deviceDiscovered(const QextPortInfo &)), - myClass, SLOT(onDeviceDiscovered(const QextPortInfo &))); - connect(enumerator, SIGNAL(deviceRemoved(const QextPortInfo &)), - myClass, SLOT(onDeviceRemoved(const QextPortInfo &))); - \endcode - - \section Credits - Windows implementation is based on Zach Gorman's work from - The Code Project (http://www.codeproject.com/system/setupdi.asp). - - OS X implementation, see - http://developer.apple.com/documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_Finding_Devices/chapter_4_section_2.html - - \author Michal Policht, Liam Staskawicz -*/ -class QEXTSERIALPORT_EXPORT QextSerialEnumerator : public QObject -{ -Q_OBJECT - public: - QextSerialEnumerator( ); - ~QextSerialEnumerator( ); - - #ifdef Q_OS_WIN - LRESULT onDeviceChangeWin( WPARAM wParam, LPARAM lParam ); - private: - /*! - * Get value of specified property from the registry. - * \param key handle to an open key. - * \param property property name. - * \return property value. - */ - static QString getRegKeyValue(HKEY key, LPCTSTR property); - - /*! - * Get specific property from registry. - * \param devInfo pointer to the device information set that contains the interface - * and its underlying device. Returned by SetupDiGetClassDevs() function. - * \param devData pointer to an SP_DEVINFO_DATA structure that defines the device instance. - * this is returned by SetupDiGetDeviceInterfaceDetail() function. - * \param property registry property. One of defined SPDRP_* constants. - * \return property string. - */ - static QString getDeviceProperty(HDEVINFO devInfo, PSP_DEVINFO_DATA devData, DWORD property); - - /*! - * Search for serial ports using setupapi. - * \param infoList list with result. - */ - static void setupAPIScan(QList & infoList); - void setUpNotificationWin( ); - static bool getDeviceDetailsWin( QextPortInfo* portInfo, HDEVINFO devInfo, - PSP_DEVINFO_DATA devData, WPARAM wParam = DBT_DEVICEARRIVAL ); - static void enumerateDevicesWin( const GUID & guidDev, QList* infoList ); - bool matchAndDispatchChangedDevice(const QString & deviceID, const GUID & guid, WPARAM wParam); - #ifdef QT_GUI_LIB - QextSerialRegistrationWidget* notificationWidget; - #endif - #endif /*Q_OS_WIN*/ - - #ifdef Q_OS_UNIX - #ifdef Q_OS_MAC - private: - /*! - * Search for serial ports using IOKit. - * \param infoList list with result. - */ - static void scanPortsOSX(QList & infoList); - static void iterateServicesOSX(io_object_t service, QList & infoList); - static bool getServiceDetailsOSX( io_object_t service, QextPortInfo* portInfo ); - - void setUpNotificationOSX( ); - void onDeviceDiscoveredOSX( io_object_t service ); - void onDeviceTerminatedOSX( io_object_t service ); - friend void deviceDiscoveredCallbackOSX( void *ctxt, io_iterator_t serialPortIterator ); - friend void deviceTerminatedCallbackOSX( void *ctxt, io_iterator_t serialPortIterator ); - - IONotificationPortRef notificationPortRef; - - #else // Q_OS_MAC - private: - /*! - * Search for serial ports on unix. - * \param infoList list with result. - */ - static void scanPortsNix(QList & infoList); - #endif // Q_OS_MAC - #endif /* Q_OS_UNIX */ - - public: - /*! - Get list of ports. - \return list of ports currently available in the system. - */ - static QList getPorts(); - /*! - Enable event-driven notifications of board discovery/removal. - */ - void setUpNotifications( ); - - signals: - /*! - A new device has been connected to the system. - - setUpNotifications() must be called first to enable event-driven device notifications. - Currently only implemented on Windows and OS X. - \param info The device that has been discovered. - */ - void deviceDiscovered( const QextPortInfo & info ); - /*! - A device has been disconnected from the system. - - setUpNotifications() must be called first to enable event-driven device notifications. - Currently only implemented on Windows and OS X. - \param info The device that was disconnected. - */ - void deviceRemoved( const QextPortInfo & info ); -}; - -#endif /*_QEXTSERIALENUMERATOR_H_*/ diff --git a/Sources/qextserialport/qextserialenumerator_osx.cpp b/Sources/qextserialport/qextserialenumerator_osx.cpp deleted file mode 100644 index 229d73f..0000000 --- a/Sources/qextserialport/qextserialenumerator_osx.cpp +++ /dev/null @@ -1,288 +0,0 @@ - - - -#include "qextserialenumerator.h" -#include -#include - -#include -#include -#include - -QextSerialEnumerator::QextSerialEnumerator( ) -{ - if( !QMetaType::isRegistered( QMetaType::type("QextPortInfo") ) ) - qRegisterMetaType("QextPortInfo"); -} - -QextSerialEnumerator::~QextSerialEnumerator( ) -{ - IONotificationPortDestroy( notificationPortRef ); -} - -// static -QList QextSerialEnumerator::getPorts() -{ - QList infoList; - io_iterator_t serialPortIterator = 0; - kern_return_t kernResult = KERN_FAILURE; - CFMutableDictionaryRef matchingDictionary; - - // first try to get any serialbsd devices, then try any USBCDC devices - if( !(matchingDictionary = IOServiceMatching(kIOSerialBSDServiceValue) ) ) { - qWarning("IOServiceMatching returned a NULL dictionary."); - return infoList; - } - CFDictionaryAddValue(matchingDictionary, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes)); - - // then create the iterator with all the matching devices - if( IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &serialPortIterator) != KERN_SUCCESS ) { - qCritical() << "IOServiceGetMatchingServices failed, returned" << kernResult; - return infoList; - } - iterateServicesOSX(serialPortIterator, infoList); - IOObjectRelease(serialPortIterator); - serialPortIterator = 0; - - if( !(matchingDictionary = IOServiceNameMatching("AppleUSBCDC")) ) { - qWarning("IOServiceNameMatching returned a NULL dictionary."); - return infoList; - } - - if( IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &serialPortIterator) != KERN_SUCCESS ) { - qCritical() << "IOServiceGetMatchingServices failed, returned" << kernResult; - return infoList; - } - iterateServicesOSX(serialPortIterator, infoList); - IOObjectRelease(serialPortIterator); - - return infoList; -} - -void QextSerialEnumerator::iterateServicesOSX(io_object_t service, QList & infoList) -{ - // Iterate through all modems found. - io_object_t usbService; - while( ( usbService = IOIteratorNext(service) ) ) - { - QextPortInfo info; - info.vendorID = 0; - info.productID = 0; - getServiceDetailsOSX( usbService, &info ); - infoList.append(info); - } -} - -bool QextSerialEnumerator::getServiceDetailsOSX( io_object_t service, QextPortInfo* portInfo ) -{ - bool retval = true; - CFTypeRef bsdPathAsCFString = NULL; - CFTypeRef productNameAsCFString = NULL; - CFTypeRef vendorIdAsCFNumber = NULL; - CFTypeRef productIdAsCFNumber = NULL; - // check the name of the modem's callout device - bsdPathAsCFString = IORegistryEntryCreateCFProperty(service, CFSTR(kIOCalloutDeviceKey), - kCFAllocatorDefault, 0); - - // wander up the hierarchy until we find the level that can give us the - // vendor/product IDs and the product name, if available - io_registry_entry_t parent; - kern_return_t kernResult = IORegistryEntryGetParentEntry(service, kIOServicePlane, &parent); - while( kernResult == KERN_SUCCESS && !vendorIdAsCFNumber && !productIdAsCFNumber ) - { - if(!productNameAsCFString) - productNameAsCFString = IORegistryEntrySearchCFProperty(parent, - kIOServicePlane, - CFSTR("Product Name"), - kCFAllocatorDefault, 0); - vendorIdAsCFNumber = IORegistryEntrySearchCFProperty(parent, - kIOServicePlane, - CFSTR(kUSBVendorID), - kCFAllocatorDefault, 0); - productIdAsCFNumber = IORegistryEntrySearchCFProperty(parent, - kIOServicePlane, - CFSTR(kUSBProductID), - kCFAllocatorDefault, 0); - io_registry_entry_t oldparent = parent; - kernResult = IORegistryEntryGetParentEntry(parent, kIOServicePlane, &parent); - IOObjectRelease(oldparent); - } - - io_string_t ioPathName; - IORegistryEntryGetPath( service, kIOServicePlane, ioPathName ); - portInfo->physName = ioPathName; - - if( bsdPathAsCFString ) - { - char path[MAXPATHLEN]; - if( CFStringGetCString((CFStringRef)bsdPathAsCFString, path, - PATH_MAX, kCFStringEncodingUTF8) ) - portInfo->portName = path; - CFRelease(bsdPathAsCFString); - } - - if(productNameAsCFString) - { - char productName[MAXPATHLEN]; - if( CFStringGetCString((CFStringRef)productNameAsCFString, productName, - PATH_MAX, kCFStringEncodingUTF8) ) - portInfo->friendName = productName; - CFRelease(productNameAsCFString); - } - - if(vendorIdAsCFNumber) - { - SInt32 vID; - if(CFNumberGetValue((CFNumberRef)vendorIdAsCFNumber, kCFNumberSInt32Type, &vID)) - portInfo->vendorID = vID; - CFRelease(vendorIdAsCFNumber); - } - - if(productIdAsCFNumber) - { - SInt32 pID; - if(CFNumberGetValue((CFNumberRef)productIdAsCFNumber, kCFNumberSInt32Type, &pID)) - portInfo->productID = pID; - CFRelease(productIdAsCFNumber); - } - IOObjectRelease(service); - return retval; -} - -// IOKit callbacks registered via setupNotifications() -void deviceDiscoveredCallbackOSX( void *ctxt, io_iterator_t serialPortIterator ); -void deviceTerminatedCallbackOSX( void *ctxt, io_iterator_t serialPortIterator ); - -void deviceDiscoveredCallbackOSX( void *ctxt, io_iterator_t serialPortIterator ) -{ - QextSerialEnumerator* qese = (QextSerialEnumerator*)ctxt; - io_object_t serialService; - while ((serialService = IOIteratorNext(serialPortIterator))) - qese->onDeviceDiscoveredOSX(serialService); -} - -void deviceTerminatedCallbackOSX( void *ctxt, io_iterator_t serialPortIterator ) -{ - QextSerialEnumerator* qese = (QextSerialEnumerator*)ctxt; - io_object_t serialService; - while ((serialService = IOIteratorNext(serialPortIterator))) - qese->onDeviceTerminatedOSX(serialService); -} - -/* - A device has been discovered via IOKit. - Create a QextPortInfo if possible, and emit the signal indicating that we've found it. -*/ -void QextSerialEnumerator::onDeviceDiscoveredOSX( io_object_t service ) -{ - QextPortInfo info; - info.vendorID = 0; - info.productID = 0; - if( getServiceDetailsOSX( service, &info ) ) - emit deviceDiscovered( info ); -} - -/* - Notification via IOKit that a device has been removed. - Create a QextPortInfo if possible, and emit the signal indicating that it's gone. -*/ -void QextSerialEnumerator::onDeviceTerminatedOSX( io_object_t service ) -{ - QextPortInfo info; - info.vendorID = 0; - info.productID = 0; - if( getServiceDetailsOSX( service, &info ) ) - emit deviceRemoved( info ); -} - -/* - Create matching dictionaries for the devices we want to get notifications for, - and add them to the current run loop. Invoke the callbacks that will be responding - to these notifications once to arm them, and discover any devices that - are currently connected at the time notifications are setup. -*/ -void QextSerialEnumerator::setUpNotifications( ) -{ - kern_return_t kernResult; - mach_port_t masterPort; - CFRunLoopSourceRef notificationRunLoopSource; - CFMutableDictionaryRef classesToMatch; - CFMutableDictionaryRef cdcClassesToMatch; - io_iterator_t portIterator; - - kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort); - if (KERN_SUCCESS != kernResult) { - qDebug() << "IOMasterPort returned:" << kernResult; - return; - } - - classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); - if (classesToMatch == NULL) - qDebug("IOServiceMatching returned a NULL dictionary."); - else - CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes)); - - if( !(cdcClassesToMatch = IOServiceNameMatching("AppleUSBCDC") ) ) { - qWarning("couldn't create cdc matching dict"); - return; - } - - // Retain an additional reference since each call to IOServiceAddMatchingNotification consumes one. - classesToMatch = (CFMutableDictionaryRef) CFRetain(classesToMatch); - cdcClassesToMatch = (CFMutableDictionaryRef) CFRetain(cdcClassesToMatch); - - notificationPortRef = IONotificationPortCreate(masterPort); - if(notificationPortRef == NULL) { - qDebug("IONotificationPortCreate return a NULL IONotificationPortRef."); - return; - } - - notificationRunLoopSource = IONotificationPortGetRunLoopSource(notificationPortRef); - if (notificationRunLoopSource == NULL) { - qDebug("IONotificationPortGetRunLoopSource returned NULL CFRunLoopSourceRef."); - return; - } - - CFRunLoopAddSource(CFRunLoopGetCurrent(), notificationRunLoopSource, kCFRunLoopDefaultMode); - - kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOMatchedNotification, classesToMatch, - deviceDiscoveredCallbackOSX, this, &portIterator); - if (kernResult != KERN_SUCCESS) { - qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; - return; - } - - // arm the callback, and grab any devices that are already connected - deviceDiscoveredCallbackOSX( this, portIterator ); - - kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOMatchedNotification, cdcClassesToMatch, - deviceDiscoveredCallbackOSX, this, &portIterator); - if (kernResult != KERN_SUCCESS) { - qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; - return; - } - - // arm the callback, and grab any devices that are already connected - deviceDiscoveredCallbackOSX( this, portIterator ); - - kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOTerminatedNotification, classesToMatch, - deviceTerminatedCallbackOSX, this, &portIterator); - if (kernResult != KERN_SUCCESS) { - qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; - return; - } - - // arm the callback, and clear any devices that are terminated - deviceTerminatedCallbackOSX( this, portIterator ); - - kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOTerminatedNotification, cdcClassesToMatch, - deviceTerminatedCallbackOSX, this, &portIterator); - if (kernResult != KERN_SUCCESS) { - qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; - return; - } - - // arm the callback, and clear any devices that are terminated - deviceTerminatedCallbackOSX( this, portIterator ); -} - diff --git a/Sources/qextserialport/qextserialenumerator_unix.cpp b/Sources/qextserialport/qextserialenumerator_unix.cpp deleted file mode 100644 index f43a75b..0000000 --- a/Sources/qextserialport/qextserialenumerator_unix.cpp +++ /dev/null @@ -1,75 +0,0 @@ - - - -#include "qextserialenumerator.h" -#include -#include -#include -#include - -QextSerialEnumerator::QextSerialEnumerator( ) -{ - if( !QMetaType::isRegistered( QMetaType::type("QextPortInfo") ) ) - qRegisterMetaType("QextPortInfo"); -} - -QextSerialEnumerator::~QextSerialEnumerator( ) -{ -} - -QList QextSerialEnumerator::getPorts() -{ - QList infoList; -#ifdef Q_OS_LINUX - QStringList portNamePrefixes, portNameList; - portNamePrefixes << "ttyS*"; // list normal serial ports first - - QDir dir("/dev"); - portNameList = dir.entryList(portNamePrefixes, (QDir::System | QDir::Files), QDir::Name); - - // remove the values which are not serial ports for e.g. /dev/ttysa - for (int i = 0; i < portNameList.size(); i++) { - bool ok; - QString current = portNameList.at(i); - // remove the ttyS part, and check, if the other part is a number - current.remove(0,4).toInt(&ok, 10); - if (!ok) { - portNameList.removeAt(i); - i--; - } - } - - // get the non standard serial ports names - // (USB-serial, bluetooth-serial, 18F PICs, and so on) - // if you know an other name prefix for serial ports please let us know - portNamePrefixes.clear(); - portNamePrefixes << "ttyACM*" << "ttyUSB*" << "rfcomm*"; - portNameList.append(dir.entryList(portNamePrefixes, (QDir::System | QDir::Files), QDir::Name)); - - foreach (QString str , portNameList) { - QextPortInfo inf; - inf.physName = "/dev/"+str; - inf.portName = str; - - if (str.contains("ttyS")) { - inf.friendName = "Serial port "+str.remove(0, 4); - } - else if (str.contains("ttyUSB")) { - inf.friendName = "USB-serial adapter "+str.remove(0, 6); - } - else if (str.contains("rfcomm")) { - inf.friendName = "Bluetooth-serial adapter "+str.remove(0, 6); - } - inf.enumName = "/dev"; // is there a more helpful name for this? - infoList.append(inf); - } -#else - qCritical("Enumeration for POSIX systems (except Linux) is not implemented yet."); -#endif - return infoList; -} - -void QextSerialEnumerator::setUpNotifications( ) -{ - qCritical("Notifications for *Nix/FreeBSD are not implemented yet"); -} diff --git a/Sources/qextserialport/qextserialenumerator_win.cpp b/Sources/qextserialport/qextserialenumerator_win.cpp deleted file mode 100644 index e2ef78c..0000000 --- a/Sources/qextserialport/qextserialenumerator_win.cpp +++ /dev/null @@ -1,206 +0,0 @@ - - - -#include "qextserialenumerator.h" -#include -#include - -#include -#include -#include "qextserialport.h" -#include - -QextSerialEnumerator::QextSerialEnumerator( ) -{ - if( !QMetaType::isRegistered( QMetaType::type("QextPortInfo") ) ) - qRegisterMetaType("QextPortInfo"); -#if (defined QT_GUI_LIB) - notificationWidget = 0; -#endif // Q_OS_WIN -} - -QextSerialEnumerator::~QextSerialEnumerator( ) -{ -#if (defined QT_GUI_LIB) - if( notificationWidget ) - delete notificationWidget; -#endif -} - - - -// see http://msdn.microsoft.com/en-us/library/ms791134.aspx for list of GUID classes -#ifndef GUID_DEVCLASS_PORTS - DEFINE_GUID(GUID_DEVCLASS_PORTS, 0x4D36E978, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 ); -#endif - -/* Gordon Schumacher's macros for TCHAR -> QString conversions and vice versa */ -#ifdef UNICODE - #define QStringToTCHAR(x) (wchar_t*) x.utf16() - #define PQStringToTCHAR(x) (wchar_t*) x->utf16() - #define TCHARToQString(x) QString::fromUtf16((ushort*)(x)) - #define TCHARToQStringN(x,y) QString::fromUtf16((ushort*)(x),(y)) -#else - #define QStringToTCHAR(x) x.local8Bit().constData() - #define PQStringToTCHAR(x) x->local8Bit().constData() - #define TCHARToQString(x) QString::fromLocal8Bit((x)) - #define TCHARToQStringN(x,y) QString::fromLocal8Bit((x),(y)) -#endif /*UNICODE*/ - - -//static -QString QextSerialEnumerator::getRegKeyValue(HKEY key, LPCTSTR property) -{ - DWORD size = 0; - DWORD type; - RegQueryValueEx(key, property, NULL, NULL, NULL, & size); - BYTE* buff = new BYTE[size]; - QString result; - if( RegQueryValueEx(key, property, NULL, &type, buff, & size) == ERROR_SUCCESS ) - result = TCHARToQString((const char *)buff); - RegCloseKey(key); - delete [] buff; - return result; -} - -//static -QString QextSerialEnumerator::getDeviceProperty(HDEVINFO devInfo, PSP_DEVINFO_DATA devData, DWORD property) -{ - DWORD buffSize = 0; - SetupDiGetDeviceRegistryProperty(devInfo, devData, property, NULL, NULL, 0, & buffSize); - BYTE* buff = new BYTE[buffSize]; - SetupDiGetDeviceRegistryProperty(devInfo, devData, property, NULL, buff, buffSize, NULL); - QString result = TCHARToQString((const char *)buff); - delete [] buff; - return result; -} - -QList QextSerialEnumerator::getPorts() -{ - QList ports; - enumerateDevicesWin(GUID_DEVCLASS_PORTS, &ports); - return ports; -} - -void QextSerialEnumerator::enumerateDevicesWin( const GUID & guid, QList* infoList ) -{ - HDEVINFO devInfo; - if( (devInfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT)) != INVALID_HANDLE_VALUE) - { - SP_DEVINFO_DATA devInfoData; - devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - for(int i = 0; SetupDiEnumDeviceInfo(devInfo, i, &devInfoData); i++) - { - QextPortInfo info; - info.productID = info.vendorID = 0; - getDeviceDetailsWin( &info, devInfo, &devInfoData ); - infoList->append(info); - } - SetupDiDestroyDeviceInfoList(devInfo); - } -} - -#ifdef QT_GUI_LIB -bool QextSerialRegistrationWidget::winEvent( MSG* message, long* result ) -{ - if ( message->message == WM_DEVICECHANGE ) { - qese->onDeviceChangeWin( message->wParam, message->lParam ); - *result = 1; - return true; - } - return false; -} -#endif - -void QextSerialEnumerator::setUpNotifications( ) -{ - #ifdef QT_GUI_LIB - if(notificationWidget) - return; - notificationWidget = new QextSerialRegistrationWidget(this); - - DEV_BROADCAST_DEVICEINTERFACE dbh; - ZeroMemory(&dbh, sizeof(dbh)); - dbh.dbcc_size = sizeof(dbh); - dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; - CopyMemory(&dbh.dbcc_classguid, &GUID_DEVCLASS_PORTS, sizeof(GUID)); - if( RegisterDeviceNotification( notificationWidget->winId( ), &dbh, DEVICE_NOTIFY_WINDOW_HANDLE ) == NULL) - qWarning() << "RegisterDeviceNotification failed:" << GetLastError(); - // setting up notifications doesn't tell us about devices already connected - // so get those manually - foreach( QextPortInfo port, getPorts() ) - emit deviceDiscovered( port ); - #else - qWarning("QextSerialEnumerator: GUI not enabled - can't register for device notifications."); - #endif // QT_GUI_LIB -} - -LRESULT QextSerialEnumerator::onDeviceChangeWin( WPARAM wParam, LPARAM lParam ) -{ - if ( DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam ) - { - PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam; - if( pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE ) - { - PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr; - // delimiters are different across APIs...change to backslash. ugh. - QString deviceID = TCHARToQString(pDevInf->dbcc_name).toUpper().replace("#", "\\"); - - matchAndDispatchChangedDevice(deviceID, GUID_DEVCLASS_PORTS, wParam); - } - } - return 0; -} - -bool QextSerialEnumerator::matchAndDispatchChangedDevice(const QString & deviceID, const GUID & guid, WPARAM wParam) -{ - bool rv = false; - DWORD dwFlag = (DBT_DEVICEARRIVAL == wParam) ? DIGCF_PRESENT : DIGCF_ALLCLASSES; - HDEVINFO devInfo; - if( (devInfo = SetupDiGetClassDevs(&guid,NULL,NULL,dwFlag)) != INVALID_HANDLE_VALUE ) - { - SP_DEVINFO_DATA spDevInfoData; - spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - for(int i=0; SetupDiEnumDeviceInfo(devInfo, i, &spDevInfoData); i++) - { - DWORD nSize=0 ; - TCHAR buf[MAX_PATH]; - if ( SetupDiGetDeviceInstanceId(devInfo, &spDevInfoData, buf, MAX_PATH, &nSize) && - deviceID.contains(TCHARToQString(buf))) // we found a match - { - rv = true; - QextPortInfo info; - info.productID = info.vendorID = 0; - getDeviceDetailsWin( &info, devInfo, &spDevInfoData, wParam ); - if( wParam == DBT_DEVICEARRIVAL ) - emit deviceDiscovered(info); - else if( wParam == DBT_DEVICEREMOVECOMPLETE ) - emit deviceRemoved(info); - break; - } - } - SetupDiDestroyDeviceInfoList(devInfo); - } - return rv; -} - -bool QextSerialEnumerator::getDeviceDetailsWin( QextPortInfo* portInfo, HDEVINFO devInfo, PSP_DEVINFO_DATA devData, WPARAM wParam ) -{ - portInfo->friendName = getDeviceProperty(devInfo, devData, SPDRP_FRIENDLYNAME); - if( wParam == DBT_DEVICEARRIVAL) - portInfo->physName = getDeviceProperty(devInfo, devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME); - portInfo->enumName = getDeviceProperty(devInfo, devData, SPDRP_ENUMERATOR_NAME); - QString hardwareIDs = getDeviceProperty(devInfo, devData, SPDRP_HARDWAREID); - HKEY devKey = SetupDiOpenDevRegKey(devInfo, devData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); - portInfo->portName = QextSerialPort::fullPortNameWin( getRegKeyValue(devKey, TEXT("PortName")) ); - QRegExp idRx("VID_(\\w+)&PID_(\\w+)"); - if( hardwareIDs.toUpper().contains(idRx) ) - { - bool dummy; - portInfo->vendorID = idRx.cap(1).toInt(&dummy, 16); - portInfo->productID = idRx.cap(2).toInt(&dummy, 16); - //qDebug() << "got vid:" << vid << "pid:" << pid; - } - return true; -} - diff --git a/Sources/qextserialport/qextserialport.cpp b/Sources/qextserialport/qextserialport.cpp deleted file mode 100644 index ccf3598..0000000 --- a/Sources/qextserialport/qextserialport.cpp +++ /dev/null @@ -1,254 +0,0 @@ - - -#include -#include "qextserialport.h" - -/*! -Default constructor. Note that the name of the device used by a QextSerialPort constructed with -this constructor will be determined by #defined constants, or lack thereof - the default behavior -is the same as _TTY_LINUX_. Possible naming conventions and their associated constants are: - -\verbatim - -Constant Used By Naming Convention ----------- ------------- ------------------------ -Q_OS_WIN Windows COM1, COM2 -_TTY_IRIX_ SGI/IRIX /dev/ttyf1, /dev/ttyf2 -_TTY_HPUX_ HP-UX /dev/tty1p0, /dev/tty2p0 -_TTY_SUN_ SunOS/Solaris /dev/ttya, /dev/ttyb -_TTY_DIGITAL_ Digital UNIX /dev/tty01, /dev/tty02 -_TTY_FREEBSD_ FreeBSD /dev/ttyd0, /dev/ttyd1 -_TTY_OPENBSD_ OpenBSD /dev/tty00, /dev/tty01 -_TTY_LINUX_ Linux /dev/ttyS0, /dev/ttyS1 - Linux /dev/ttyS0, /dev/ttyS1 -\endverbatim - -This constructor assigns the device name to the name of the first port on the specified system. -See the other constructors if you need to open a different port. -*/ -QextSerialPort::QextSerialPort(QextSerialPort::QueryMode mode) - : QIODevice() -{ - -#ifdef Q_OS_WIN - setPortName("COM1"); - -#elif defined(_TTY_IRIX_) - setPortName("/dev/ttyf1"); - -#elif defined(_TTY_HPUX_) - setPortName("/dev/tty1p0"); - -#elif defined(_TTY_SUN_) - setPortName("/dev/ttya"); - -#elif defined(_TTY_DIGITAL_) - setPortName("/dev/tty01"); - -#elif defined(_TTY_FREEBSD_) - setPortName("/dev/ttyd1"); - -#elif defined(_TTY_OPENBSD_) - setPortName("/dev/tty00"); - -#else - setPortName("/dev/ttyS0"); -#endif - - construct(); - setQueryMode(mode); - platformSpecificInit(); -} - -/*! -Constructs a serial port attached to the port specified by name. -name is the name of the device, which is windowsystem-specific, -e.g."COM1" or "/dev/ttyS0". -*/ -QextSerialPort::QextSerialPort(const QString & name, QextSerialPort::QueryMode mode) - : QIODevice() -{ - construct(); - setQueryMode(mode); - setPortName(name); - platformSpecificInit(); -} - -/*! -Constructs a port with default name and specified settings. -*/ -QextSerialPort::QextSerialPort(const PortSettings& settings, QextSerialPort::QueryMode mode) - : QIODevice() -{ - construct(); - setBaudRate(settings.BaudRate); - setDataBits(settings.DataBits); - setParity(settings.Parity); - setStopBits(settings.StopBits); - setFlowControl(settings.FlowControl); - setTimeout(settings.Timeout_Millisec); - setQueryMode(mode); - platformSpecificInit(); -} - -/*! -Constructs a port with specified name and settings. -*/ -QextSerialPort::QextSerialPort(const QString & name, const PortSettings& settings, QextSerialPort::QueryMode mode) - : QIODevice() -{ - construct(); - setPortName(name); - setBaudRate(settings.BaudRate); - setDataBits(settings.DataBits); - setParity(settings.Parity); - setStopBits(settings.StopBits); - setFlowControl(settings.FlowControl); - setTimeout(settings.Timeout_Millisec); - setQueryMode(mode); - platformSpecificInit(); -} - -/*! -Common constructor function for setting up default port settings. -(115200 Baud, 8N1, Hardware flow control where supported, otherwise no flow control, and 0 ms timeout). -*/ -void QextSerialPort::construct() -{ - lastErr = E_NO_ERROR; - Settings.BaudRate=BAUD115200; - Settings.DataBits=DATA_8; - Settings.Parity=PAR_NONE; - Settings.StopBits=STOP_1; - Settings.FlowControl=FLOW_HARDWARE; - Settings.Timeout_Millisec=500; - mutex = new QMutex( QMutex::Recursive ); - setOpenMode(QIODevice::NotOpen); -} - -void QextSerialPort::setQueryMode(QueryMode mechanism) -{ - _queryMode = mechanism; -} - -/*! -Sets the name of the device associated with the object, e.g. "COM1", or "/dev/ttyS0". -*/ -void QextSerialPort::setPortName(const QString & name) -{ - #ifdef Q_OS_WIN - port = fullPortNameWin( name ); - #else - port = name; - #endif -} - -/*! -Returns the name set by setPortName(). -*/ -QString QextSerialPort::portName() const -{ - return port; -} - -/*! - Reads all available data from the device, and returns it as a QByteArray. - This function has no way of reporting errors; returning an empty QByteArray() - can mean either that no data was currently available for reading, or that an error occurred. -*/ -QByteArray QextSerialPort::readAll() -{ - int avail = this->bytesAvailable(); - return (avail > 0) ? this->read(avail) : QByteArray(); -} - -/*! -Returns the baud rate of the serial port. For a list of possible return values see -the definition of the enum BaudRateType. -*/ -BaudRateType QextSerialPort::baudRate(void) const -{ - return Settings.BaudRate; -} - -/*! -Returns the number of data bits used by the port. For a list of possible values returned by -this function, see the definition of the enum DataBitsType. -*/ -DataBitsType QextSerialPort::dataBits() const -{ - return Settings.DataBits; -} - -/*! -Returns the type of parity used by the port. For a list of possible values returned by -this function, see the definition of the enum ParityType. -*/ -ParityType QextSerialPort::parity() const -{ - return Settings.Parity; -} - -/*! -Returns the number of stop bits used by the port. For a list of possible return values, see -the definition of the enum StopBitsType. -*/ -StopBitsType QextSerialPort::stopBits() const -{ - return Settings.StopBits; -} - -/*! -Returns the type of flow control used by the port. For a list of possible values returned -by this function, see the definition of the enum FlowType. -*/ -FlowType QextSerialPort::flowControl() const -{ - return Settings.FlowControl; -} - -/*! -Returns true if device is sequential, otherwise returns false. Serial port is sequential device -so this function always returns true. Check QIODevice::isSequential() documentation for more -information. -*/ -bool QextSerialPort::isSequential() const -{ - return true; -} - -QString QextSerialPort::errorString() -{ - switch(lastErr) - { - case E_NO_ERROR: return "No Error has occurred"; - case E_INVALID_FD: return "Invalid file descriptor (port was not opened correctly)"; - case E_NO_MEMORY: return "Unable to allocate memory tables (POSIX)"; - case E_CAUGHT_NON_BLOCKED_SIGNAL: return "Caught a non-blocked signal (POSIX)"; - case E_PORT_TIMEOUT: return "Operation timed out (POSIX)"; - case E_INVALID_DEVICE: return "The file opened by the port is not a valid device"; - case E_BREAK_CONDITION: return "The port detected a break condition"; - case E_FRAMING_ERROR: return "The port detected a framing error (usually caused by incorrect baud rate settings)"; - case E_IO_ERROR: return "There was an I/O error while communicating with the port"; - case E_BUFFER_OVERRUN: return "Character buffer overrun"; - case E_RECEIVE_OVERFLOW: return "Receive buffer overflow"; - case E_RECEIVE_PARITY_ERROR: return "The port detected a parity error in the received data"; - case E_TRANSMIT_OVERFLOW: return "Transmit buffer overflow"; - case E_READ_FAILED: return "General read operation failure"; - case E_WRITE_FAILED: return "General write operation failure"; - case E_FILE_NOT_FOUND: return "The "+this->portName()+" file doesn't exists"; - default: return QString("Unknown error: %1").arg(lastErr); - } -} - -/*! -Standard destructor. -*/ -QextSerialPort::~QextSerialPort() -{ - if (isOpen()) { - close(); - } - platformSpecificDestruct(); - delete mutex; -} diff --git a/Sources/qextserialport/qextserialport.h b/Sources/qextserialport/qextserialport.h deleted file mode 100644 index 13a0db5..0000000 --- a/Sources/qextserialport/qextserialport.h +++ /dev/null @@ -1,333 +0,0 @@ - -#ifndef _QEXTSERIALPORT_H_ -#define _QEXTSERIALPORT_H_ - -#include "qextserialport_global.h" - -/*if all warning messages are turned off, flag portability warnings to be turned off as well*/ -#ifdef _TTY_NOWARN_ -#define _TTY_NOWARN_PORT_ -#endif - -/*macros for warning and debug messages*/ -#ifdef _TTY_NOWARN_PORT_ -#define TTY_PORTABILITY_WARNING(s) -#else -#define TTY_PORTABILITY_WARNING(s) qWarning(s) -#endif /*_TTY_NOWARN_PORT_*/ -#ifdef _TTY_NOWARN_ -#define TTY_WARNING(s) -#else -#define TTY_WARNING(s) qWarning(s) -#endif /*_TTY_NOWARN_*/ - - -/*line status constants*/ -#define LS_CTS 0x01 -#define LS_DSR 0x02 -#define LS_DCD 0x04 -#define LS_RI 0x08 -#define LS_RTS 0x10 -#define LS_DTR 0x20 -#define LS_ST 0x40 -#define LS_SR 0x80 - -/*error constants*/ -#define E_NO_ERROR 0 -#define E_INVALID_FD 1 -#define E_NO_MEMORY 2 -#define E_CAUGHT_NON_BLOCKED_SIGNAL 3 -#define E_PORT_TIMEOUT 4 -#define E_INVALID_DEVICE 5 -#define E_BREAK_CONDITION 6 -#define E_FRAMING_ERROR 7 -#define E_IO_ERROR 8 -#define E_BUFFER_OVERRUN 9 -#define E_RECEIVE_OVERFLOW 10 -#define E_RECEIVE_PARITY_ERROR 11 -#define E_TRANSMIT_OVERFLOW 12 -#define E_READ_FAILED 13 -#define E_WRITE_FAILED 14 -#define E_FILE_NOT_FOUND 15 - -enum BaudRateType -{ - BAUD50, //POSIX ONLY - BAUD75, //POSIX ONLY - BAUD110, - BAUD134, //POSIX ONLY - BAUD150, //POSIX ONLY - BAUD200, //POSIX ONLY - BAUD300, - BAUD600, - BAUD1200, - BAUD1800, //POSIX ONLY - BAUD2400, - BAUD4800, - BAUD9600, - BAUD14400, //WINDOWS ONLY - BAUD19200, - BAUD38400, - BAUD56000, //WINDOWS ONLY - BAUD57600, - BAUD76800, //POSIX ONLY - BAUD115200, - BAUD128000, //WINDOWS ONLY - BAUD256000 //WINDOWS ONLY -}; - -enum DataBitsType -{ - DATA_5, - DATA_6, - DATA_7, - DATA_8 -}; - -enum ParityType -{ - PAR_NONE, - PAR_ODD, - PAR_EVEN, - PAR_MARK, //WINDOWS ONLY - PAR_SPACE -}; - -enum StopBitsType -{ - STOP_1, - STOP_1_5, //WINDOWS ONLY - STOP_2 -}; - -enum FlowType -{ - FLOW_OFF, - FLOW_HARDWARE, - FLOW_XONXOFF -}; - -/** - * structure to contain port settings - */ -struct PortSettings -{ - BaudRateType BaudRate; - DataBitsType DataBits; - ParityType Parity; - StopBitsType StopBits; - FlowType FlowControl; - long Timeout_Millisec; -}; - -#include -#include -#ifdef Q_OS_UNIX -#include -#include -#include -#include -#include -#include -#include -#include -#elif (defined Q_OS_WIN) -#include -#include -#include -#include -#endif - -/*! -Encapsulates a serial port on both POSIX and Windows systems. - -\note -Be sure to check the full list of members, as QIODevice provides quite a lot of -functionality for QextSerialPort. - -\section Usage -QextSerialPort offers both a polling and event driven API. Event driven is typically easier -to use, since you never have to worry about checking for new data. - -\b Example -\code -QextSerialPort* port = new QextSerialPort("COM1", QextSerialPort::EventDriven); -connect(port, SIGNAL(readyRead()), myClass, SLOT(onDataAvailable())); -port->open(); - -void MyClass::onDataAvailable() { - int avail = port->bytesAvailable(); - if( avail > 0 ) { - QByteArray usbdata; - usbdata.resize(avail); - int read = port->read(usbdata.data(), usbdata.size()); - if( read > 0 ) { - processNewData(usbdata); - } - } -} -\endcode - -\section Compatibility -The user will be notified of errors and possible portability conflicts at run-time -by default - this behavior can be turned off by defining _TTY_NOWARN_ -(to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn off portability warnings) in the project. - -On Windows NT/2000/XP this class uses Win32 serial port functions by default. The user may -select POSIX behavior under NT, 2000, or XP ONLY by defining Q_OS_UNIX in the project. -No guarantees are made as to the quality of POSIX support under NT/2000 however. - -\author Stefan Sander, Michal Policht, Brandon Fosdick, Liam Staskawicz -*/ -class QEXTSERIALPORT_EXPORT QextSerialPort: public QIODevice -{ - Q_OBJECT - public: - enum QueryMode { - Polling, - EventDriven - }; - - QextSerialPort(QueryMode mode = EventDriven); - QextSerialPort(const QString & name, QueryMode mode = EventDriven); - QextSerialPort(PortSettings const& s, QueryMode mode = EventDriven); - QextSerialPort(const QString & name, PortSettings const& s, QueryMode mode = EventDriven); - ~QextSerialPort(); - - void setPortName(const QString & name); - QString portName() const; - - /**! - * Get query mode. - * \return query mode. - */ - inline QueryMode queryMode() const { return _queryMode; } - - /*! - * Set desired serial communication handling style. You may choose from polling - * or event driven approach. This function does nothing when port is open; to - * apply changes port must be reopened. - * - * In event driven approach read() and write() functions are acting - * asynchronously. They return immediately and the operation is performed in - * the background, so they doesn't freeze the calling thread. - * To determine when operation is finished, QextSerialPort runs separate thread - * and monitors serial port events. Whenever the event occurs, adequate signal - * is emitted. - * - * When polling is set, read() and write() are acting synchronously. Signals are - * not working in this mode and some functions may not be available. The advantage - * of polling is that it generates less overhead due to lack of signals emissions - * and it doesn't start separate thread to monitor events. - * - * Generally event driven approach is more capable and friendly, although some - * applications may need as low overhead as possible and then polling comes. - * - * \param mode query mode. - */ - void setQueryMode(QueryMode mode); - - void setBaudRate(BaudRateType); - BaudRateType baudRate() const; - - void setDataBits(DataBitsType); - DataBitsType dataBits() const; - - void setParity(ParityType); - ParityType parity() const; - - void setStopBits(StopBitsType); - StopBitsType stopBits() const; - - void setFlowControl(FlowType); - FlowType flowControl() const; - - void setTimeout(long); - - bool open(OpenMode mode); - bool isSequential() const; - void close(); - void flush(); - - qint64 size() const; - qint64 bytesAvailable() const; - QByteArray readAll(); - - void ungetChar(char c); - - ulong lastError() const; - void translateError(ulong error); - - void setDtr(bool set=true); - void setRts(bool set=true); - ulong lineStatus(); - QString errorString(); - -#ifdef Q_OS_WIN - virtual bool waitForReadyRead(int msecs); ///< @todo implement. - virtual qint64 bytesToWrite() const; - static QString fullPortNameWin(const QString & name); -#endif - - protected: - QMutex* mutex; - QString port; - PortSettings Settings; - ulong lastErr; - QueryMode _queryMode; - - // platform specific members -#ifdef Q_OS_UNIX - int fd; - QSocketNotifier *readNotifier; - struct termios Posix_CommConfig; - struct termios old_termios; - struct timeval Posix_Timeout; - struct timeval Posix_Copy_Timeout; -#elif (defined Q_OS_WIN) - HANDLE Win_Handle; - OVERLAPPED overlap; - COMMCONFIG Win_CommConfig; - COMMTIMEOUTS Win_CommTimeouts; - QWinEventNotifier *winEventNotifier; - DWORD eventMask; - QList pendingWrites; - QReadWriteLock* bytesToWriteLock; - qint64 _bytesToWrite; -#endif - - void construct(); // common construction - void platformSpecificDestruct(); - void platformSpecificInit(); - qint64 readData(char * data, qint64 maxSize); - qint64 writeData(const char * data, qint64 maxSize); - -#ifdef Q_OS_WIN - private slots: - void onWinEvent(HANDLE h); -#endif - - private: - Q_DISABLE_COPY(QextSerialPort) - - signals: -// /** -// * This signal is emitted whenever port settings are updated. -// * \param valid \p true if settings are valid, \p false otherwise. -// * -// * @todo implement. -// */ -// // void validSettings(bool valid); - - /*! - * This signal is emitted whenever dsr line has changed its state. You may - * use this signal to check if device is connected. - * \param status \p true when DSR signal is on, \p false otherwise. - * - * \see lineStatus(). - */ - void dsrChanged(bool status); - -}; - -#endif diff --git a/Sources/qextserialport/qextserialport_global.h b/Sources/qextserialport/qextserialport_global.h deleted file mode 100644 index 63ad657..0000000 --- a/Sources/qextserialport/qextserialport_global.h +++ /dev/null @@ -1,18 +0,0 @@ - - -#ifndef QEXTSERIALPORT_GLOBAL_H -#define QEXTSERIALPORT_GLOBAL_H - -#include - -#ifdef QEXTSERIALPORT_LIB -# define QEXTSERIALPORT_EXPORT Q_DECL_EXPORT -#else -# define QEXTSERIALPORT_EXPORT Q_DECL_IMPORT -#endif - -#undef QEXTSERIALPORT_EXPORT -#define QEXTSERIALPORT_EXPORT - -#endif // QEXTSERIALPORT_GLOBAL_H - diff --git a/Sources/qextserialport/qwineventnotifier_p.h b/Sources/qextserialport/qwineventnotifier_p.h deleted file mode 100644 index 459cd67..0000000 --- a/Sources/qextserialport/qwineventnotifier_p.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWINEVENTNOTIFIER_P_H -#define QWINEVENTNOTIFIER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "QtCore/qobject.h" -#include "QtCore/qt_windows.h" - -QT_BEGIN_NAMESPACE - -class Q_CORE_EXPORT QWinEventNotifier : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QObject) - -public: - explicit QWinEventNotifier(QObject *parent = 0); - explicit QWinEventNotifier(HANDLE hEvent, QObject *parent = 0); - ~QWinEventNotifier(); - - void setHandle(HANDLE hEvent); - HANDLE handle() const; - - bool isEnabled() const; - -public Q_SLOTS: - void setEnabled(bool enable); - -Q_SIGNALS: - void activated(HANDLE hEvent); - -protected: - bool event(QEvent * e); - -private: - Q_DISABLE_COPY(QWinEventNotifier) - - HANDLE handleToEvent; - bool enabled; -}; - -QT_END_NAMESPACE - -#endif // QWINEVENTNOTIFIER_P_H diff --git a/Sources/qextserialport/win_qextserialport.cpp b/Sources/qextserialport/win_qextserialport.cpp deleted file mode 100644 index af1cdb6..0000000 --- a/Sources/qextserialport/win_qextserialport.cpp +++ /dev/null @@ -1,868 +0,0 @@ - - -#include -#include -#include -#include "qextserialport.h" - -void QextSerialPort::platformSpecificInit() -{ - Win_Handle=INVALID_HANDLE_VALUE; - ZeroMemory(&overlap, sizeof(OVERLAPPED)); - overlap.hEvent = CreateEvent(NULL, true, false, NULL); - winEventNotifier = 0; - bytesToWriteLock = new QReadWriteLock; - _bytesToWrite = 0; -} - -/*! -Standard destructor. -*/ -void QextSerialPort::platformSpecificDestruct() { - CloseHandle(overlap.hEvent); - delete bytesToWriteLock; -} - -QString QextSerialPort::fullPortNameWin(const QString & name) -{ - QRegExp rx("^COM(\\d+)"); - QString fullName(name); - if(fullName.contains(rx)) { - int portnum = rx.cap(1).toInt(); - if(portnum > 9) // COM ports greater than 9 need \\.\ prepended - fullName.prepend("\\\\.\\"); - } - return fullName; -} - -/*! -Opens a serial port. Note that this function does not specify which device to open. If you need -to open a device by name, see QextSerialPort::open(const char*). This function has no effect -if the port associated with the class is already open. The port is also configured to the current -settings, as stored in the Settings structure. -*/ -bool QextSerialPort::open(OpenMode mode) { - unsigned long confSize = sizeof(COMMCONFIG); - Win_CommConfig.dwSize = confSize; - DWORD dwFlagsAndAttributes = 0; - if (queryMode() == QextSerialPort::EventDriven) - dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED; - - QMutexLocker lock(mutex); - if (mode == QIODevice::NotOpen) - return isOpen(); - if (!isOpen()) { - /*open the port*/ - Win_Handle=CreateFileA(port.toAscii(), GENERIC_READ|GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL); - if (Win_Handle!=INVALID_HANDLE_VALUE) { - QIODevice::open(mode); - /*configure port settings*/ - GetCommConfig(Win_Handle, &Win_CommConfig, &confSize); - GetCommState(Win_Handle, &(Win_CommConfig.dcb)); - - /*set up parameters*/ - Win_CommConfig.dcb.fBinary=TRUE; - Win_CommConfig.dcb.fInX=FALSE; - Win_CommConfig.dcb.fOutX=FALSE; - Win_CommConfig.dcb.fAbortOnError=FALSE; - Win_CommConfig.dcb.fNull=FALSE; - setBaudRate(Settings.BaudRate); - setDataBits(Settings.DataBits); - setStopBits(Settings.StopBits); - setParity(Settings.Parity); - setFlowControl(Settings.FlowControl); - setTimeout(Settings.Timeout_Millisec); - SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); - - //init event driven approach - if (queryMode() == QextSerialPort::EventDriven) { - Win_CommTimeouts.ReadIntervalTimeout = MAXDWORD; - Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0; - Win_CommTimeouts.ReadTotalTimeoutConstant = 0; - Win_CommTimeouts.WriteTotalTimeoutMultiplier = 0; - Win_CommTimeouts.WriteTotalTimeoutConstant = 0; - SetCommTimeouts(Win_Handle, &Win_CommTimeouts); - if (!SetCommMask( Win_Handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) { - qWarning() << "failed to set Comm Mask. Error code:", GetLastError(); - return false; - } - winEventNotifier = new QWinEventNotifier(overlap.hEvent, this); - connect(winEventNotifier, SIGNAL(activated(HANDLE)), this, SLOT(onWinEvent(HANDLE))); - WaitCommEvent(Win_Handle, &eventMask, &overlap); - } - } - } else { - return false; - } - return isOpen(); -} - -/*! -Closes a serial port. This function has no effect if the serial port associated with the class -is not currently open. -*/ -void QextSerialPort::close() -{ - QMutexLocker lock(mutex); - if (isOpen()) { - flush(); - QIODevice::close(); // mark ourselves as closed - CancelIo(Win_Handle); - if (CloseHandle(Win_Handle)) - Win_Handle = INVALID_HANDLE_VALUE; - if (winEventNotifier) - winEventNotifier->deleteLater(); - - _bytesToWrite = 0; - - foreach(OVERLAPPED* o, pendingWrites) { - CloseHandle(o->hEvent); - delete o; - } - pendingWrites.clear(); - } -} - -/*! -Flushes all pending I/O to the serial port. This function has no effect if the serial port -associated with the class is not currently open. -*/ -void QextSerialPort::flush() { - QMutexLocker lock(mutex); - if (isOpen()) { - FlushFileBuffers(Win_Handle); - } -} - -/*! -This function will return the number of bytes waiting in the receive queue of the serial port. -It is included primarily to provide a complete QIODevice interface, and will not record errors -in the lastErr member (because it is const). This function is also not thread-safe - in -multithreading situations, use QextSerialPort::bytesAvailable() instead. -*/ -qint64 QextSerialPort::size() const { - int availBytes; - COMSTAT Win_ComStat; - DWORD Win_ErrorMask=0; - ClearCommError(Win_Handle, &Win_ErrorMask, &Win_ComStat); - availBytes = Win_ComStat.cbInQue; - return (qint64)availBytes; -} - -/*! -Returns the number of bytes waiting in the port's receive queue. This function will return 0 if -the port is not currently open, or -1 on error. -*/ -qint64 QextSerialPort::bytesAvailable() const { - QMutexLocker lock(mutex); - if (isOpen()) { - DWORD Errors; - COMSTAT Status; - if (ClearCommError(Win_Handle, &Errors, &Status)) { - return Status.cbInQue + QIODevice::bytesAvailable(); - } - return (qint64)-1; - } - return 0; -} - -/*! -Translates a system-specific error code to a QextSerialPort error code. Used internally. -*/ -void QextSerialPort::translateError(ulong error) { - if (error&CE_BREAK) { - lastErr=E_BREAK_CONDITION; - } - else if (error&CE_FRAME) { - lastErr=E_FRAMING_ERROR; - } - else if (error&CE_IOE) { - lastErr=E_IO_ERROR; - } - else if (error&CE_MODE) { - lastErr=E_INVALID_FD; - } - else if (error&CE_OVERRUN) { - lastErr=E_BUFFER_OVERRUN; - } - else if (error&CE_RXPARITY) { - lastErr=E_RECEIVE_PARITY_ERROR; - } - else if (error&CE_RXOVER) { - lastErr=E_RECEIVE_OVERFLOW; - } - else if (error&CE_TXFULL) { - lastErr=E_TRANSMIT_OVERFLOW; - } -} - -/*! -Reads a block of data from the serial port. This function will read at most maxlen bytes from -the serial port and place them in the buffer pointed to by data. Return value is the number of -bytes actually read, or -1 on error. - -\warning before calling this function ensure that serial port associated with this class -is currently open (use isOpen() function to check if port is open). -*/ -qint64 QextSerialPort::readData(char *data, qint64 maxSize) -{ - DWORD retVal; - QMutexLocker lock(mutex); - retVal = 0; - if (queryMode() == QextSerialPort::EventDriven) { - OVERLAPPED overlapRead; - ZeroMemory(&overlapRead, sizeof(OVERLAPPED)); - if (!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, & overlapRead)) { - if (GetLastError() == ERROR_IO_PENDING) - GetOverlappedResult(Win_Handle, & overlapRead, & retVal, true); - else { - lastErr = E_READ_FAILED; - retVal = (DWORD)-1; - } - } - } else if (!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, NULL)) { - lastErr = E_READ_FAILED; - retVal = (DWORD)-1; - } - return (qint64)retVal; -} - -/*! -Writes a block of data to the serial port. This function will write len bytes -from the buffer pointed to by data to the serial port. Return value is the number -of bytes actually written, or -1 on error. - -\warning before calling this function ensure that serial port associated with this class -is currently open (use isOpen() function to check if port is open). -*/ -qint64 QextSerialPort::writeData(const char *data, qint64 maxSize) -{ - QMutexLocker lock( mutex ); - DWORD retVal = 0; - if (queryMode() == QextSerialPort::EventDriven) { - OVERLAPPED* newOverlapWrite = new OVERLAPPED; - ZeroMemory(newOverlapWrite, sizeof(OVERLAPPED)); - newOverlapWrite->hEvent = CreateEvent(NULL, true, false, NULL); - if (WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, newOverlapWrite)) { - CloseHandle(newOverlapWrite->hEvent); - delete newOverlapWrite; - } - else if (GetLastError() == ERROR_IO_PENDING) { - // writing asynchronously...not an error - QWriteLocker writelocker(bytesToWriteLock); - _bytesToWrite += maxSize; - pendingWrites.append(newOverlapWrite); - } - else { - qDebug() << "serialport write error:" << GetLastError(); - lastErr = E_WRITE_FAILED; - retVal = (DWORD)-1; - if(!CancelIo(newOverlapWrite->hEvent)) - qDebug() << "serialport: couldn't cancel IO"; - if(!CloseHandle(newOverlapWrite->hEvent)) - qDebug() << "serialport: couldn't close OVERLAPPED handle"; - delete newOverlapWrite; - } - } else if (!WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, NULL)) { - lastErr = E_WRITE_FAILED; - retVal = (DWORD)-1; - } - return (qint64)retVal; -} - -/*! -This function is included to implement the full QIODevice interface, and currently has no -purpose within this class. This function is meaningless on an unbuffered device and currently -only prints a warning message to that effect. -*/ -void QextSerialPort::ungetChar(char c) { - - /*meaningless on unbuffered sequential device - return error and print a warning*/ - TTY_WARNING("QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless"); -} - -/*! -Sets the flow control used by the port. Possible values of flow are: -\verbatim - FLOW_OFF No flow control - FLOW_HARDWARE Hardware (RTS/CTS) flow control - FLOW_XONXOFF Software (XON/XOFF) flow control -\endverbatim -*/ -void QextSerialPort::setFlowControl(FlowType flow) { - QMutexLocker lock(mutex); - if (Settings.FlowControl!=flow) { - Settings.FlowControl=flow; - } - if (isOpen()) { - switch(flow) { - - /*no flow control*/ - case FLOW_OFF: - Win_CommConfig.dcb.fOutxCtsFlow=FALSE; - Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE; - Win_CommConfig.dcb.fInX=FALSE; - Win_CommConfig.dcb.fOutX=FALSE; - SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); - break; - - /*software (XON/XOFF) flow control*/ - case FLOW_XONXOFF: - Win_CommConfig.dcb.fOutxCtsFlow=FALSE; - Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE; - Win_CommConfig.dcb.fInX=TRUE; - Win_CommConfig.dcb.fOutX=TRUE; - SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); - break; - - case FLOW_HARDWARE: - Win_CommConfig.dcb.fOutxCtsFlow=TRUE; - Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_HANDSHAKE; - Win_CommConfig.dcb.fInX=FALSE; - Win_CommConfig.dcb.fOutX=FALSE; - SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); - break; - } - } -} - -/*! -Sets the parity associated with the serial port. The possible values of parity are: -\verbatim - PAR_SPACE Space Parity - PAR_MARK Mark Parity - PAR_NONE No Parity - PAR_EVEN Even Parity - PAR_ODD Odd Parity -\endverbatim -*/ -void QextSerialPort::setParity(ParityType parity) { - QMutexLocker lock(mutex); - if (Settings.Parity!=parity) { - Settings.Parity=parity; - } - if (isOpen()) { - Win_CommConfig.dcb.Parity=(unsigned char)parity; - switch (parity) { - - /*space parity*/ - case PAR_SPACE: - if (Settings.DataBits==DATA_8) { - TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Space parity with 8 data bits is not supported by POSIX systems."); - } - Win_CommConfig.dcb.fParity=TRUE; - break; - - /*mark parity - WINDOWS ONLY*/ - case PAR_MARK: - TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Mark parity is not supported by POSIX systems"); - Win_CommConfig.dcb.fParity=TRUE; - break; - - /*no parity*/ - case PAR_NONE: - Win_CommConfig.dcb.fParity=FALSE; - break; - - /*even parity*/ - case PAR_EVEN: - Win_CommConfig.dcb.fParity=TRUE; - break; - - /*odd parity*/ - case PAR_ODD: - Win_CommConfig.dcb.fParity=TRUE; - break; - } - SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); - } -} - -/*! -Sets the number of data bits used by the serial port. Possible values of dataBits are: -\verbatim - DATA_5 5 data bits - DATA_6 6 data bits - DATA_7 7 data bits - DATA_8 8 data bits -\endverbatim - -\note -This function is subject to the following restrictions: -\par - 5 data bits cannot be used with 2 stop bits. -\par - 1.5 stop bits can only be used with 5 data bits. -\par - 8 data bits cannot be used with space parity on POSIX systems. -*/ -void QextSerialPort::setDataBits(DataBitsType dataBits) { - QMutexLocker lock(mutex); - if (Settings.DataBits!=dataBits) { - if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) || - (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5)) { - } - else { - Settings.DataBits=dataBits; - } - } - if (isOpen()) { - switch(dataBits) { - - /*5 data bits*/ - case DATA_5: - if (Settings.StopBits==STOP_2) { - TTY_WARNING("QextSerialPort: 5 Data bits cannot be used with 2 stop bits."); - } - else { - Win_CommConfig.dcb.ByteSize=5; - SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); - } - break; - - /*6 data bits*/ - case DATA_6: - if (Settings.StopBits==STOP_1_5) { - TTY_WARNING("QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits."); - } - else { - Win_CommConfig.dcb.ByteSize=6; - SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); - } - break; - - /*7 data bits*/ - case DATA_7: - if (Settings.StopBits==STOP_1_5) { - TTY_WARNING("QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits."); - } - else { - Win_CommConfig.dcb.ByteSize=7; - SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); - } - break; - - /*8 data bits*/ - case DATA_8: - if (Settings.StopBits==STOP_1_5) { - TTY_WARNING("QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits."); - } - else { - Win_CommConfig.dcb.ByteSize=8; - SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); - } - break; - } - } -} - -/*! -Sets the number of stop bits used by the serial port. Possible values of stopBits are: -\verbatim - STOP_1 1 stop bit - STOP_1_5 1.5 stop bits - STOP_2 2 stop bits -\endverbatim - -\note -This function is subject to the following restrictions: -\par - 2 stop bits cannot be used with 5 data bits. -\par - 1.5 stop bits cannot be used with 6 or more data bits. -\par - POSIX does not support 1.5 stop bits. -*/ -void QextSerialPort::setStopBits(StopBitsType stopBits) { - QMutexLocker lock(mutex); - if (Settings.StopBits!=stopBits) { - if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) || - (stopBits==STOP_1_5 && Settings.DataBits!=DATA_5)) { - } - else { - Settings.StopBits=stopBits; - } - } - if (isOpen()) { - switch (stopBits) { - - /*one stop bit*/ - case STOP_1: - Win_CommConfig.dcb.StopBits=ONESTOPBIT; - SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); - break; - - /*1.5 stop bits*/ - case STOP_1_5: - TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: 1.5 stop bit operation is not supported by POSIX."); - if (Settings.DataBits!=DATA_5) { - TTY_WARNING("QextSerialPort: 1.5 stop bits can only be used with 5 data bits"); - } - else { - Win_CommConfig.dcb.StopBits=ONE5STOPBITS; - SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); - } - break; - - /*two stop bits*/ - case STOP_2: - if (Settings.DataBits==DATA_5) { - TTY_WARNING("QextSerialPort: 2 stop bits cannot be used with 5 data bits"); - } - else { - Win_CommConfig.dcb.StopBits=TWOSTOPBITS; - SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); - } - break; - } - } -} - -/*! -Sets the baud rate of the serial port. Note that not all rates are applicable on -all platforms. The following table shows translations of the various baud rate -constants on Windows(including NT/2000) and POSIX platforms. Speeds marked with an * -are speeds that are usable on both Windows and POSIX. -\verbatim - - RATE Windows Speed POSIX Speed - ----------- ------------- ----------- - BAUD50 110 50 - BAUD75 110 75 - *BAUD110 110 110 - BAUD134 110 134.5 - BAUD150 110 150 - BAUD200 110 200 - *BAUD300 300 300 - *BAUD600 600 600 - *BAUD1200 1200 1200 - BAUD1800 1200 1800 - *BAUD2400 2400 2400 - *BAUD4800 4800 4800 - *BAUD9600 9600 9600 - BAUD14400 14400 9600 - *BAUD19200 19200 19200 - *BAUD38400 38400 38400 - BAUD56000 56000 38400 - *BAUD57600 57600 57600 - BAUD76800 57600 76800 - *BAUD115200 115200 115200 - BAUD128000 128000 115200 - BAUD256000 256000 115200 -\endverbatim -*/ -void QextSerialPort::setBaudRate(BaudRateType baudRate) { - QMutexLocker lock(mutex); - if (Settings.BaudRate!=baudRate) { - switch (baudRate) { - case BAUD50: - case BAUD75: - case BAUD134: - case BAUD150: - case BAUD200: - Settings.BaudRate=BAUD110; - break; - - case BAUD1800: - Settings.BaudRate=BAUD1200; - break; - - case BAUD76800: - Settings.BaudRate=BAUD57600; - break; - - default: - Settings.BaudRate=baudRate; - break; - } - } - if (isOpen()) { - switch (baudRate) { - - /*50 baud*/ - case BAUD50: - TTY_WARNING("QextSerialPort: Windows does not support 50 baud operation. Switching to 110 baud."); - Win_CommConfig.dcb.BaudRate=CBR_110; - break; - - /*75 baud*/ - case BAUD75: - TTY_WARNING("QextSerialPort: Windows does not support 75 baud operation. Switching to 110 baud."); - Win_CommConfig.dcb.BaudRate=CBR_110; - break; - - /*110 baud*/ - case BAUD110: - Win_CommConfig.dcb.BaudRate=CBR_110; - break; - - /*134.5 baud*/ - case BAUD134: - TTY_WARNING("QextSerialPort: Windows does not support 134.5 baud operation. Switching to 110 baud."); - Win_CommConfig.dcb.BaudRate=CBR_110; - break; - - /*150 baud*/ - case BAUD150: - TTY_WARNING("QextSerialPort: Windows does not support 150 baud operation. Switching to 110 baud."); - Win_CommConfig.dcb.BaudRate=CBR_110; - break; - - /*200 baud*/ - case BAUD200: - TTY_WARNING("QextSerialPort: Windows does not support 200 baud operation. Switching to 110 baud."); - Win_CommConfig.dcb.BaudRate=CBR_110; - break; - - /*300 baud*/ - case BAUD300: - Win_CommConfig.dcb.BaudRate=CBR_300; - break; - - /*600 baud*/ - case BAUD600: - Win_CommConfig.dcb.BaudRate=CBR_600; - break; - - /*1200 baud*/ - case BAUD1200: - Win_CommConfig.dcb.BaudRate=CBR_1200; - break; - - /*1800 baud*/ - case BAUD1800: - TTY_WARNING("QextSerialPort: Windows does not support 1800 baud operation. Switching to 1200 baud."); - Win_CommConfig.dcb.BaudRate=CBR_1200; - break; - - /*2400 baud*/ - case BAUD2400: - Win_CommConfig.dcb.BaudRate=CBR_2400; - break; - - /*4800 baud*/ - case BAUD4800: - Win_CommConfig.dcb.BaudRate=CBR_4800; - break; - - /*9600 baud*/ - case BAUD9600: - Win_CommConfig.dcb.BaudRate=CBR_9600; - break; - - /*14400 baud*/ - case BAUD14400: - TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: POSIX does not support 14400 baud operation."); - Win_CommConfig.dcb.BaudRate=CBR_14400; - break; - - /*19200 baud*/ - case BAUD19200: - Win_CommConfig.dcb.BaudRate=CBR_19200; - break; - - /*38400 baud*/ - case BAUD38400: - Win_CommConfig.dcb.BaudRate=CBR_38400; - break; - - /*56000 baud*/ - case BAUD56000: - TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: POSIX does not support 56000 baud operation."); - Win_CommConfig.dcb.BaudRate=CBR_56000; - break; - - /*57600 baud*/ - case BAUD57600: - Win_CommConfig.dcb.BaudRate=CBR_57600; - break; - - /*76800 baud*/ - case BAUD76800: - TTY_WARNING("QextSerialPort: Windows does not support 76800 baud operation. Switching to 57600 baud."); - Win_CommConfig.dcb.BaudRate=CBR_57600; - break; - - /*115200 baud*/ - case BAUD115200: - Win_CommConfig.dcb.BaudRate=CBR_115200; - break; - - /*128000 baud*/ - case BAUD128000: - TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: POSIX does not support 128000 baud operation."); - Win_CommConfig.dcb.BaudRate=CBR_128000; - break; - - /*256000 baud*/ - case BAUD256000: - TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: POSIX does not support 256000 baud operation."); - Win_CommConfig.dcb.BaudRate=CBR_256000; - break; - } - SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); - } -} - -/*! -Sets DTR line to the requested state (high by default). This function will have no effect if -the port associated with the class is not currently open. -*/ -void QextSerialPort::setDtr(bool set) { - QMutexLocker lock(mutex); - if (isOpen()) { - if (set) { - EscapeCommFunction(Win_Handle, SETDTR); - } - else { - EscapeCommFunction(Win_Handle, CLRDTR); - } - } -} - -/*! -Sets RTS line to the requested state (high by default). This function will have no effect if -the port associated with the class is not currently open. -*/ -void QextSerialPort::setRts(bool set) { - QMutexLocker lock(mutex); - if (isOpen()) { - if (set) { - EscapeCommFunction(Win_Handle, SETRTS); - } - else { - EscapeCommFunction(Win_Handle, CLRRTS); - } - } -} - -/*! -Returns the line status as stored by the port function. This function will retrieve the states -of the following lines: DCD, CTS, DSR, and RI. On POSIX systems, the following additional lines -can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD. The value returned is an unsigned -long with specific bits indicating which lines are high. The following constants should be used -to examine the states of individual lines: - -\verbatim -Mask Line ------- ---- -LS_CTS CTS -LS_DSR DSR -LS_DCD DCD -LS_RI RI -\endverbatim - -This function will return 0 if the port associated with the class is not currently open. -*/ -ulong QextSerialPort::lineStatus(void) { - unsigned long Status=0, Temp=0; - QMutexLocker lock(mutex); - if (isOpen()) { - GetCommModemStatus(Win_Handle, &Temp); - if (Temp&MS_CTS_ON) { - Status|=LS_CTS; - } - if (Temp&MS_DSR_ON) { - Status|=LS_DSR; - } - if (Temp&MS_RING_ON) { - Status|=LS_RI; - } - if (Temp&MS_RLSD_ON) { - Status|=LS_DCD; - } - } - return Status; -} - -bool QextSerialPort::waitForReadyRead(int msecs) -{ - //@todo implement - return false; -} - -qint64 QextSerialPort::bytesToWrite() const -{ - QReadLocker rl(bytesToWriteLock); - return _bytesToWrite; -} - -/* - Triggered when there's activity on our HANDLE. -*/ -void QextSerialPort::onWinEvent(HANDLE h) -{ - QMutexLocker lock(mutex); - if(h == overlap.hEvent) { - if (eventMask & EV_RXCHAR) { - if (sender() != this && bytesAvailable() > 0) - emit readyRead(); - } - if (eventMask & EV_TXEMPTY) { - /* - A write completed. Run through the list of OVERLAPPED writes, and if - they completed successfully, take them off the list and delete them. - Otherwise, leave them on there so they can finish. - */ - qint64 totalBytesWritten = 0; - QList overlapsToDelete; - foreach(OVERLAPPED* o, pendingWrites) { - DWORD numBytes = 0; - if (GetOverlappedResult(Win_Handle, o, & numBytes, false)) { - overlapsToDelete.append(o); - totalBytesWritten += numBytes; - } else if( GetLastError() != ERROR_IO_INCOMPLETE ) { - overlapsToDelete.append(o); - qWarning() << "CommEvent overlapped write error:" << GetLastError(); - } - } - - if (sender() != this && totalBytesWritten > 0) { - QWriteLocker writelocker(bytesToWriteLock); - emit bytesWritten(totalBytesWritten); - _bytesToWrite = 0; - } - - foreach(OVERLAPPED* o, overlapsToDelete) { - OVERLAPPED *toDelete = pendingWrites.takeAt(pendingWrites.indexOf(o)); - CloseHandle(toDelete->hEvent); - delete toDelete; - } - } - if (eventMask & EV_DSR) { - if (lineStatus() & LS_DSR) - emit dsrChanged(true); - else - emit dsrChanged(false); - } - } - WaitCommEvent(Win_Handle, &eventMask, &overlap); -} - -/*! -Sets the read and write timeouts for the port to millisec milliseconds. -Setting 0 indicates that timeouts are not used for read nor write operations; -however read() and write() functions will still block. Set -1 to provide -non-blocking behaviour (read() and write() will return immediately). - -\note this function does nothing in event driven mode. -*/ -void QextSerialPort::setTimeout(long millisec) { - QMutexLocker lock(mutex); - Settings.Timeout_Millisec = millisec; - - if (millisec == -1) { - Win_CommTimeouts.ReadIntervalTimeout = MAXDWORD; - Win_CommTimeouts.ReadTotalTimeoutConstant = 0; - } else { - Win_CommTimeouts.ReadIntervalTimeout = millisec; - Win_CommTimeouts.ReadTotalTimeoutConstant = millisec; - } - Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0; - Win_CommTimeouts.WriteTotalTimeoutMultiplier = millisec; - Win_CommTimeouts.WriteTotalTimeoutConstant = 0; - if (queryMode() != QextSerialPort::EventDriven) - SetCommTimeouts(Win_Handle, &Win_CommTimeouts); -} - diff --git a/libcrypto-1_1-x64.dll b/libcrypto-1_1-x64.dll new file mode 100644 index 0000000..35bb8cb Binary files /dev/null and b/libcrypto-1_1-x64.dll differ diff --git a/libssl-1_1-x64.dll b/libssl-1_1-x64.dll new file mode 100644 index 0000000..aa7b84e Binary files /dev/null and b/libssl-1_1-x64.dll differ